现有一棵n个结点的二叉树(结点编号为从0
到n-1
),已知其先序序列和中序序列,求后序序列。
解题思路:
利用好两个序列的特性:
先序是:根,左儿子,右儿子。
中序是:左儿子,根,右儿子。
因此可以利用先序的根,在中序中进行分治递归。
如例子中的:利用先序的0,将中序分为左儿子:1 2 4,右儿子5 3
递归,利用先序的2,将左儿子分为:左左儿子:1,左右儿子:4;利用先序的5,分为右左儿子为空,右右儿子为3
叶子节点的体现在于:PreL>PreR.
完整代码如下:
#include <iostream>
#include <vector>
using namespace std;
vector<int> pre,in;
struct node{
int lchild;
int rchild;
} nodes[51];
bool flag = false;
void PstOrderTraverse(int root){
if(root == -1){
return ;
}
PstOrderTraverse(nodes[root].lchild);
PstOrderTraverse(nodes[root].rchild);
if(flag) cout<<" ";
cout<<root;
flag = true;
}
int MakeTree(int PreL,int PreR,int InL,int InR){
if(PreL>PreR){
return -1;
}
int root = pre[PreL];
int inPos;
for(int i=InL;i<=InR;i++){
if(in[i]==root){
inPos = i;
break;
}
}
int leftcount = inPos-InL;
nodes[root].lchild = MakeTree(PreL+1,PreL+leftcount,InL,inPos-1);
nodes[root].rchild = MakeTree(PreL+leftcount+1,PreR,inPos+1,InR);
return root;
}
int main(){
int n;
cin>>n;
int temp;
for(int i=0;i<n;i++){
cin>>temp;
pre.push_back(temp);
}
for(int i=0;i<n;i++){
cin>>temp;
in.push_back(temp);
}
int root = MakeTree(0,n-1,0,n-1);
PstOrderTraverse(root);
return 0;
}