已知二叉樹的中序遍歷和先序/后序遍歷求后序/先序


已知兩種遍歷序列求原始二叉樹

算法思想:

需要明確的前提條件

  • 通過先序和中序可以求出原始二叉樹
  • 通過中序和后序可以求出原始二叉樹
  • 但是通過先序和后序無法還原出二叉樹

換種說法:

  • 只有通過先序中序或者后序中序才可以確定一個二叉樹

先來看一個例子,已知先序遍歷序列和中序遍歷序列求后序遍歷: 
先序:ABCDEFGH 
中序:BDCEAFHG 
求后序: 
分析:要求后序遍歷序列,必須求出原始二叉樹 
先看先序序列A第一個出現,有先序遍歷的定義可以知道A是根結點 
再看中序遍歷,A的左邊是BDCE,而A的右邊是FHG 
求原始二叉樹1 
BDCE哪個是根呢?答案還是從先序遍歷找,因為先序遍歷根最先出現 
再看B、D、C、E中在先序遍歷中最先出現的是B,所以B是BDCE中的根, 
由於B是根,在看中序遍歷中B左端沒有樹,所以DCE是B的右子樹 
求原始二叉樹2 
而在DCE中,誰又是根? 
同樣的我們看先序遍歷序列C先出現,所以C是DCE中的根, 
而此時在中序遍歷中C的左端只有一個D,C的右端只有一個E 
根據中序遍歷的定義D是C的左子樹,E是C的右子樹 
求原始二叉樹3 
接着我們再看FHG,F、H、G在先序遍歷中最先出現的是F,所以F是FHG中的根, 
再回到中序遍歷FHG中F左端再沒有結點,右端是HG所以HG是F的右子樹 
求原始二叉樹4 
再看HG中誰是根,在先序遍歷中G先出現,所以G是根 
再看中序遍歷,G的左端只有一個H,右端沒有子樹,說明H是G的左子樹 
求原始二叉樹5 
這樣我們就得到了一個原始二叉樹,題目的要求是讓求這個二叉樹的后序遍歷序列, 
這樣我們可以根據二叉樹后序遍歷的定義 
寫出該二叉樹的后序遍歷序列: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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM