题目描述:
现有两个结点序列,分别是对同一个二叉树进行前序遍历和中序遍历的结果。请编写一个程序,输出该二叉树按后序遍历时的结点序列。
输入:
第1行输入二叉树的结点数n。
第2行输入前序遍历的结点编号序列,相邻编号用空格隔开。
第3行输入中序遍历的结点编号序列,相邻编号用空格隔开。
结点编号为从1至n的整数。请注意,1不一定是根结点。
输出:
在1行中输出按后序遍历时的结点编号序列。相邻结点编号之间用1个空格隔开。
限制:
1≤结点数≤100
参考代码:
#include<bits/stdc++.h>
using namespace std;
struct Node{
int p,l,r; //p中存放父母的编号,l中存放左孩子编号 r中存放右孩子编号 。若无为-1
};
Node T[105]; //定义结构体储存树的信息
int n,pre[105],mid[105],t=0,root; //pre[105]中放先序遍历 mid[105]中放中序遍历
void POST(int u){ //后序遍历输出函数
if(u==-1) return;
POST(T[u].l);
POST(T[u].r);
cout<<u<<" ";
}
int find_node(int u){ //该函数用于:对于给定的编号u ,在中序遍历中寻找其位置,并返回
for(int i=1;i<=n;i++){
if(mid[i]==u)
return i;
}
}
void create_tree(int tem_l,int tem_r,int tem_pre,int tem_root) //树的构建函数 ,也是本程序的核心部分
{ //函数参数tem_l表示目前处理的中序遍历数组的左边界 ,参数tem_r表示目前处理的中序遍历数组的右边界
t=tem_pre; //参数tem_pre表示目前在处理前序遍历数组元素的下标 ,参数tem_root表示目前在处理的结点编号
if(tem_l==tem_r){ //若左右边界相等,一定没有子孩子了,返回
return ;
}
int tem_root_add;
tem_root_add=find_node(tem_root); //将在中序遍历中找到的当前要处理的结点的位置上储存在tem_root_add
if(tem_root_add-tem_l>0){ //构建当前结点的左孩子,父母找孩子,同时孩子找到父母
T[tem_root].l=pre[tem_pre+1];
T[pre[tem_pre+1]].p=tem_root;
}
if(tem_r-tem_root_add>0){ //构建当前结点的右孩子,父母找孩子,同时孩子找到父母
T[tem_root].r=pre[tem_pre+tem_root_add-tem_l+1];
T[pre[tem_pre+tem_root_add-tem_l+1]].p=tem_root;
}
if(tem_root_add-tem_l>0){
t++;
create_tree(tem_l,tem_root_add-1,t,pre[t]); //递归处理 tem_root_add 左边的数组
}
if(tem_r-tem_root_add>0){
t++;
create_tree(tem_root_add+1,tem_r,t,pre[t]); //递归处理 tem_root_add 右边的数组
}
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)
cin>>pre[i];
for(int i=1;i<=n;i++)
cin>>mid[i];
for(int i=1;i<=n;i++) T[i].p=T[i].l=T[i].r=-1; //树初始化
create_tree(1,n,1,pre[1]);
for(int i=1;i<=n;i++){
if(T[i].p==-1) root=i; //若此处没有处理根节点,则导致当编号不为 1的结点为根结点时发生错误
}
POST(root);
}