已知兩種遍歷序列求原始二叉樹
算法思想:
需要明確的前提條件
- 通過先序和中序可以求出原始二叉樹
- 通過中序和后序可以求出原始二叉樹
- 但是通過先序和后序無法還原出二叉樹
換種說法:
- 只有通過先序中序或者后序中序才可以確定一個二叉樹
先來看一個例子,已知先序遍歷序列和中序遍歷序列求后序遍歷:
先序:ABCDEFGH
中序:BDCEAFHG
求后序:
分析:要求后序遍歷序列,必須求出原始二叉樹
先看先序序列A第一個出現,有先序遍歷的定義可以知道A是根結點
再看中序遍歷,A的左邊是BDCE,而A的右邊是FHG
BDCE哪個是根呢?答案還是從先序遍歷找,因為先序遍歷根最先出現
再看B、D、C、E中在先序遍歷中最先出現的是B,所以B是BDCE中的根,
由於B是根,在看中序遍歷中B左端沒有樹,所以DCE是B的右子樹
而在DCE中,誰又是根?
同樣的我們看先序遍歷序列C先出現,所以C是DCE中的根,
而此時在中序遍歷中C的左端只有一個D,C的右端只有一個E
根據中序遍歷的定義D是C的左子樹,E是C的右子樹
接着我們再看FHG,F、H、G在先序遍歷中最先出現的是F,所以F是FHG中的根,
再回到中序遍歷FHG中F左端再沒有結點,右端是HG所以HG是F的右子樹
再看HG中誰是根,在先序遍歷中G先出現,所以G是根
再看中序遍歷,G的左端只有一個H,右端沒有子樹,說明H是G的左子樹
這樣我們就得到了一個原始二叉樹,題目的要求是讓求這個二叉樹的后序遍歷序列,
這樣我們可以根據二叉樹后序遍歷的定義
寫出該二叉樹的后序遍歷序列:DECBHGFA
以上轉載至:http://blog.csdn.net/dean_deng/article/details/47053231
算法實現:
1 #include<stdio.h> 2 #include<string.h> 3 #include<vector> 4 using namespace std; 5 const int N=33; 6 int z[N],h[N],x[N],n; 7 //已知中序后序 求先序 8 void dfs(int r,int zl,int zr) 9 { 10 //h[r]就是當前根的值 11 printf("%d ",h[r]); 12 int rt,lz,rz; 13 for(rt=1;rt<=n&&h[r]!=z[rt];rt++);//找到當前根在中序里的位置,可用標記數組替代 14 lz=rt-zl;rz=zr-rt;//根據中序判斷左右區間大小 15 if(lz>0) dfs(r-rz-1,zl,rt-1); 16 if(rz>0) dfs(r-1,rt+1,zr); 17 } 18 //已知中序先序 求后序 19 void dfs2(int l,int zl,int zr) 20 { 21 int rt,lz,rz; 22 for(rt=1;rt<=n&&x[l]!=z[rt];rt++);//找到當前根在中序里的位置,可用標記數組替代 23 lz=rt-zl;rz=zr-rt;//根據中序判斷左右區間大小 24 if(lz>0) dfs2(l+1,zl,rt-1); 25 if(rz>0) dfs2(l+lz+1,rt+1,zr); 26 printf("%d ",x[l]); 27 } 28 int main() 29 { 30 int i,j; 31 scanf("%d",&n); 32 for(i=1;i<=n;i++) 33 scanf("%d",&x[i]); 34 for(i=1;i<=n;i++) 35 scanf("%d",&z[i]); 36 dfs2(1,1,n);//dfs(n,1,n); 37 puts(""); 38 return 0; 39 }