二叉樹的重建
前面幾篇筆記講了二叉樹的表達與遍歷。那麼,有沒可能根據二叉樹遍歷的結果,來重建出一棵二叉樹呢?答案是肯定的。
給出二叉樹前序遍歷的結果和中序遍歷的結果,我們就能根據這些資訊,重新生成二叉樹。這個問題相對來說有挑戰性,需要花費更長的時間來思考。
看下面這棵樹:
前序遍歷結果為pre=
中序遍歷結果為in=
我們可以發現,設前序遍歷的當前節點為c,則在中序遍歷的結果中,c點左側和右側就可以構成左子樹和右子樹。也就是說,把中序結果分成兩半了。比如,前序當前為1時,那麼中序的3,2,5,4,6都屬於以1為父節點的左子樹,7,8,9都屬於以1為父結點的右子樹。以此類推,我們就可以通過遞迴來重建整棵二叉樹。
注意事項
我們在處理遞迴問題的時候,需要處理好區間邊界的問題。也就是說,要明確我們的區間是開區間還是閉區間。不然很有可能就因為這區間的問題而導致程式出錯。
而且,臨界問題也容易出錯。在這個問題裡面就是結點的左子結點為空和右子結點為空的情況。所以,我在下面的程式裡,用了兩個標記變數去標記他們的左右子結點是否為空,為空則把它們指向nil。
**實現
#include#include#include#includeusing namespace std;
#define max 100
#define nil -1
struct node
;node t[max];
int n;
vectorst,mi;
int pos=0;
node reconstruct(int left,int right)
pos++;
int m = distance(mi.begin(), find(mi.begin(), mi.end(), root));
node tmp1 = reconstruct(left,m);
node tmp2 = reconstruct(m+1,right);
if(tmp1.is_left_null)
else
if(tmp2.is_right_null)
else
t[root].id = root;
return t[root];}/*
void check()
if(t[i].left==0)
t[i].left = nil;
if(t[i].right == 0)
t[i].right = nil;
}}*/
void postorder(int u)
postorder(t[u].left);
postorder(t[u].right);
printf("%d", u);
if(u!=st[0])
cout<
}int main()
for(int i=0;i>tt;
mi.push_back(tt);
}reconstruct(0,n);
//check();
for(int i=1;i<=n;i++)
{cout<
資料結構與演算法之二叉樹
樹同時具有鍊錶和陣列的優點,關於樹的術語有 根 樹頂端的節點 葉子節點 沒有子節點的節點 樹那個節點所對應的資料結構 節點物件類,包含資料 public class node 將資料插到樹中 public void inser int id,double dd public boolean dele...
資料結構與演算法之二叉樹
陣列的優缺點 鍊錶的優缺點 缺點 在進行查詢時,效率仍然較低,需要從頭節點開始遍歷,時間複雜度為o n 樹的優點 能提高資料儲存和讀取的效率,比如利用二叉搜尋樹,既可以保證資料的查詢速度,同時也可以保證資料的插入,刪除,修改的速度。樹的常用術語 結合示意圖理解 樹的基本性質 二叉樹 每個節點最多只能...
重建二叉樹python 資料結構 重建二叉樹
說明 給定輸入一棵二叉樹的前序遍歷和中序遍歷陣列。利用此重新建立二叉樹。注意輸入不包含相同的鍵值,否則情況複雜得多。思路 由定義,前序遍歷的第乙個記錄總是根節點,而這個鍵值在中序遍歷時,將中序遍歷的陣列分成兩部分,分別對應這個根節點的左右兩子樹。同時,前序遍歷陣列跟在節點後的陣列也分成兩部分,其中前...