已知二叉樹的中序遍歷和前序遍歷,如何求後序遍歷

2021-06-07 05:22:01 字數 3044 閱讀 8123

假設有棵樹,長下面這個樣子,它的前序遍歷,中序遍歷,後續遍歷都很容易知道。

preorder:         gdafemhz

inorder:            adefghmz

postorder:       aefdhzmg

現在,假設僅僅知道前序和中序遍歷,如何求後序遍歷呢?比如,已知一棵樹的前序遍歷是」gdafemhz」,而中序遍歷是」adefghmz」應該如何求後續遍歷?

第一步,root最簡單,前序遍歷的第一節點g就是root。

第二步,繼續觀察前序遍歷gdafemhz,除了知道g是root,剩下的節點必然是root的左右子樹之外,沒法找到更多資訊了。

第三步,那就觀察中序遍歷adefghmz。其中root節點g左側的adef必然是root的左子樹,g右側的hmz必然是root的右子樹。

第四步,觀察左子樹adef,左子樹的中的根節點必然是大樹的root的leftchild。在前序遍歷中,大樹的root的leftchild位於root之後,所以左子樹的根節點為d。

第五步,同樣的道理,root的右子樹節點hmz中的根節點也可以通過前序遍歷求得。在前序遍歷中,一定是先把root和root的所有左子樹節點遍歷完之後才會遍歷右子樹,並且遍歷的右子樹的第乙個節點就是右子樹的根節點。

如何知道**是前序遍歷中的左子樹和右子樹的分界線呢?通過中序遍歷去數節點的個數。

在上一次中序遍歷中,root左側是a、d、e、f,所以有4個節點位於root左側。那麼在前序遍歷中,必然是第1個是g,第2到第5個由a、d、e、f過程,第6個就是root的右子樹的根節點了,是m。

第六步,觀察發現,上面的過程是遞迴的。先找到當前樹的根節點,然後劃分為左子樹,右子樹,然後進入左子樹重複上面的過程,然後進入右子樹重複上面的過程。最後就可以還原一棵樹了。

第七步,其實,如果僅僅要求寫後續遍歷,甚至不要專門占用空間儲存還原後的樹。只需要稍微改動第六步,就能實現要求。僅需要把第六步的遞迴的過程改動為如下:

1 確定根,確定左子樹,確定右子樹。

2 在左子樹中遞迴。

3 在右子樹中遞迴。

4 列印當前根。

參考了一些網上的討論,具體程式是:

[cpp]view plain

copy

print?

#include "stdafx.h"

#include 

using

namespace std;  

struct treenode  

;  treenode* binarytreefromorderings(char* inorder, char* preorder, int length)  

treenode* node = new treenode;//noice that [new] should be written out.

node->elem = *preorder;  

int rootindex = 0;  

for(;rootindex 

node->left = binarytreefromorderings(inorder, preorder +1, rootindex);  

node->right = binarytreefromorderings(inorder + rootindex + 1, preorder + rootindex + 1, length - (rootindex + 1));  

cout

}  int main(int argc, char* argv)    

#include "stdafx.h"

#include using namespace std;

struct treenode

;treenode* binarytreefromorderings(char* inorder, char* preorder, int length)

treenode* node = new treenode;//noice that [new] should be written out.

node->elem = *preorder;

int rootindex = 0;

for(;rootindex < length; rootindex++)//a variation of the loop

node->left = binarytreefromorderings(inorder, preorder +1, rootindex);

node->right = binarytreefromorderings(inorder + rootindex + 1, preorder + rootindex + 1, length - (rootindex + 1));

cout

其實上面的**寫得不夠簡潔。題目只要求輸出後續遍歷,並沒有要求建樹。所以,不需要去計算出node->left與node->right,也不需要去return node。改進版本如下

[cpp]view plain

copy

print?

struct treenode  

;  void binarytreefromorderings(char* inorder, char* preorder, int length)  

treenode* node = new treenode;//noice that [new] should be written out.

node->elem = *preorder;  

int rootindex = 0;  

for(;rootindex 

//left

binarytreefromorderings(inorder, preorder +1, rootindex);  

//right

binarytreefromorderings(inorder + rootindex + 1, preorder + rootindex + 1, length - (rootindex + 1));  

cout

}  int main(int argc, char* argv)    

已知前序遍歷和中序遍歷求二叉樹

輸入某二叉樹的前序遍歷和中序遍歷的結果,請輸出後序遍歷序列。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列和中序遍歷序列,重建二叉樹並返回後序遍歷序列 輸入某二叉樹的前序遍歷和中序遍歷的結果 輸出後序遍歷序列 1 2 4 7 3 5 6 8 4 7 2 1 5 3 8 6...

二叉樹 已知前序遍歷和中序遍歷,輸出後續遍歷

已知某二叉樹的先序序列和中序序列,程式設計計算並輸出該二叉樹的後序序列。輸入說明 僅一組資料,分為兩行輸入,第一行表示指定二叉樹的先序序列,第二行表示該二叉樹的中序序列,序列元素均為大寫英文本元,表示二叉樹的結點。輸出說明 在一行上輸出該二叉樹的後序序列。輸入樣本 abdgcefh dgbaechf...

已知前序和中序遍歷恢復二叉樹

cpp view plain copy include using namespace std define treelen 6 資料結構定義 struct node void rebuild char ppreorder,char pinorder,intntreelen,node proot 獲...