题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=83498#problem/D
题意:
利用二叉树的先序遍历和中序遍历序列,求出后序遍历序列,输出后序遍历序列。(可输入多组案例,每个字符串是不超过26个不同字母组成的)
案例:
input
DBACEGF ABCDEFG
BCAD CBAD
output
ACBFGED
CDAB
思路分析:
先序=根节点+左子树+右子树
中序=左子树+根节点+右子树
后序=左子树+右子树+根节点
由上述可知,根节点在先序序列中都处于最前面的位置,而在中序中是处于中间的位置,则可以先找到根节点在把左右分成两个不同的序列,通过相关计算找出两个序列在先序的位 置,而树的每一层都有节点,可通过递归找出每一层的节点。建立树。
因为在后序中节点处于最后的位置,则可进行倒叙储存。
后序是先左子树再右子树,而节点是进行倒序储存,所以要先进行右子树的寻找,再进行左子树节点的寻找。
递归需要结束条件,如果节点等于中序遍历序列的最前位,则左子树为空,结束左子树节点的寻找。如果节点等于中序遍历序列的最后位,则右子树为空,结束右子树节点的寻找。
源代码如下:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 char a[30],b[30],c[30]; 6 int n,m; 7 void build(int x1,int y1,int x2,int y2) 8 { 9 m--; 10 c[m]=a[x1]; //倒叙储存节点 11 int i=x2; 12 while(b[i]!=c[m])i++; //找到中序遍历序列中节点的位置 13 int s=i-x2; 14 if(i!=y2)build(x1+s+1,y1,i+1,y2); //寻找右子树节点 15 if(i!=x2)build(x1+1,x1+s,x2,i-1); //寻找左子树节点 16 } 17 int main() 18 { 19 while(scanf("%s%s",a,b)!=EOF) 20 { 21 n=strlen(a); //求出序列长和节点个数 22 m=n; 23 build(0,n-1,0,n-1); //建立树 24 for(int i=0;i<n;i++) 25 cout<<c[i]; 26 cout<<endl; 27 } 28 return 0; 29 }