二叉树的几种遍历相互求法
首先明确一点:知二求一的前提条件是已知的两种遍历必须要存在中序遍历,因为先序遍历和后序遍历是负责找到根节点的而分不清左右子树交界的地方。
根据后序遍历和中序遍历输出先序遍历
采用递归的写法,每次“二分”(不断分成左边和右边两部分),通过后序遍历的最后一个值确定当前的根节点,然后根据根节点在在中序遍历的位置求出左子树的元素个数,继而可知右子树的元素个数,进行递归
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int maxn=1001; 6 int pre[maxn],post[maxn],in[maxn],cnt; 7 8 void ans(int a,int b,int n) //a为post尾部的位置 9 { 10 int i; 11 if ( n==1 ) { 12 pre[++cnt]=post[a]; 13 return; 14 } 15 else if ( n<=0 ) return; 16 pre[++cnt]=post[a]; 17 for ( i=0;post[a]!=in[i+b];i++); 18 ans(a-n+i,b,i); //post尾部的位置 in头部的位置 代表左子树 19 ans(a-1,b+i+1,n-i-1); //代表右子树 20 } 21 22 int main() 23 { 24 int n,i; 25 while ( scanf("%d",&n)!=EOF ) { 26 for ( i=1;i<=n;i++ ) scanf("%d",&post[i]); 27 for ( i=1;i<=n;i++ ) scanf("%d",&in[i]); 28 cnt=0; 29 ans(n,1,n); 30 for ( i=1;i<=n;i++ ) printf("%d ",pre[i]); 31 printf("\n"); 32 } 33 return 0; 34 }
根据前序遍历和中序遍历求后序遍历
原理同上,前序遍历的第一个值为当前的根节点
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int maxn=1001; 6 int pre[maxn],post[maxn],in[maxn],cnt; 7 8 void ans(int a,int b,int n) 9 { 10 if ( n==1 ) { //如果存在左子树/右子树直接输出 11 post[++cnt]=pre[a]; 12 return; 13 } 14 else if ( n<=0 ) return; //不存在子树则返回 15 int i; 16 for ( i=0;pre[a]!=in[b+i];i++ ); 17 ans(a+1,b,i); 18 ans(a+i+1,b+i+1,n-i-1); 19 post[++cnt]=pre[a]; 20 } 21 22 int main() 23 { 24 int n,i; 25 while ( scanf("%d",&n)!=EOF ) { 26 for ( i=1;i<=n;i++ ) scanf("%d",&pre[i]); 27 for ( i=1;i<=n;i++ ) scanf("%d",&in[i]); 28 cnt=0; 29 ans(1,1,n); //前序头部的位置 中序头部的位置 长度 30 for ( i=1;i<=n;i++ ) printf("%d ",post[i]); 31 printf("\n"); 32 } 33 return 0; 34 }