已知两种遍历序列求原始二叉树
算法思想:
需要明确的前提条件
- 通过先序和中序可以求出原始二叉树
- 通过中序和后序可以求出原始二叉树
- 但是通过先序和后序无法还原出二叉树
换种说法:
- 只有通过先序中序或者后序中序才可以确定一个二叉树
先来看一个例子,已知先序遍历序列和中序遍历序列求后序遍历:
先序: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 }
时间: 2024-10-04 00:52:21