题目:输入二叉树的先序和中序遍历序列,求后序遍历。
(1)输入样例:
先序:1 2 4 7 3 5 8 9 6
中序:4 7 2 1 8 5 9 3 6
(2)输出样例:
后序:7 4 2 8 9 5 6 3 1
思路:
(1)利用先序和中序虚拟出树的图像。
(2)利用后序遍历性质,在树上进行遍历,输出。
代码:
由于代码中含有解释,因此就不一步一步去分析了。总体还是很简单的。
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;//这里依据结点个数
int pre[N],in[N],post[N];//先序、中序、后序
int k;
struct node{
int value;
node *l,*r;
node(int value = 0,node *l = NULL,node *r = NULL):value(value),l(l),r(r){}
};
void buildtree(int l,int r,int &t,node* &root ){//模拟树
int flag = -1;
for(int i=l;i<=r;i++)//先序的第一个位置是根,找到对应的中序的位置
if(in[i] == pre[t]){
flag = i;break;
}
if(flag == -1) return;//表示所搜查的范围不存在根,结束
root =new node(in[flag]);//新建结点
t++;
if(flag >l) buildtree(l,flag-1,t,root->l);
if(flag <r) buildtree(flag+1,r,t,root->r);
}
//下面的是在虚拟树完成后,才可以进行的
//假如题目给的是:中序+后序,则只需改变上面的部分程序,其他的只需稍作调整即可
void preorder(node *root){//求先序序列
if(root !=NULL){
post[k++] = root ->value;//输出
preorder(root ->l);
preorder(root ->r);
}
}
void inorder(node *root){//求中序序列
if(root !=NULL){
inorder(root ->l);
post[k++] = root ->value;//输出
inorder(root ->r);
}
}
void postorder(node *root){//求后序序列
if(root !=NULL){
postorder(root ->l);
postorder(root ->r);
post[k++] = root ->value;
}
}
//释放空间(如果不释放,会造成内存泄漏,造成内存浪费)
void remove_tree(node *root){//释放空间
if(root ==NULL) return;
remove_tree(root ->l);
remove_tree(root ->r);
delete root;
}
int main(){
int n;
while(~scanf("%d",&n)){
for(int i=1;i<=n;i++) scanf("%d",&pre[i]);
for(int j=1;j<=n;j++) scanf("%d",&in[j]);
node *root;
int t =1;
buildtree(1,n,t,root);
k =0;//记录结点数
postorder(root);
for(int i=0;i<k;i++) printf("%d%c",post[i],i ==k-1? '\n':' ');
remove_tree(root);
}
return 0;
}