一.题目
【问题描述】
已知二叉树的先序和中序遍历序列,推出它的后序遍历序列。【输入】: 共两行,第1行一个字符串,表示树的先序遍历,第2行一个字符串,表示树的中序遍历。树的结点一律用小写字母表示
【输出】: 仅一行,表示树的后序遍历序列。
【样例输入】
abdec
dbeac
【样例输出】
debca
二.思路
1.首先要建树
num为左子树的个数:i-inL
左子树的先序范围:(preL+1,preL+num)
中序范围:(inL,i-1)
右子树的先序范围:(preL+num+1,preR)
中序范围:(i+1,inR)
最终建得的树长这样
三.核心代码(建树)
int create(int preL,int preR,int inL,int inR,int bt){
//一开始数据就有问题,无法建树;
if(preL>preR){
bt=0;
}else{
bt=++ent;
int i;
for(i=inL;i<inR;i++){
if(in[i]==pre[preL]){
break;
}
}
data[bt].value=in[i];
int num=i-inL; //左子树有多少个
data[bt].lchild=create(preL+1,preL+num,inL,i-1,bt); //左子树递归
data[bt].rchild=create(preL+num+1,preR,i+1,inR,bt); //右子树递归
}
return bt;
}
四.最终代码
#include<iostream>
#include<cstring>
using namespace std;
char pre[1001],in[1001];
int root,ent=0; //根节点 && 每个节点的编号
struct node{
char value;
int lchild,rchild;
}data[1001];
int n; //树的节点数
int create(int preL,int preR,int inL,int inR,int bt){
//一开始数据就有问题,无法建树;
if(preL>preR){
bt=0;
}else{
bt=++ent;
int i;
for(i=inL;i<inR;i++){
if(in[i]==pre[preL]){
break;
}
}
data[bt].value=in[i];
int num=i-inL; //左子树有多少个
data[bt].lchild=create(preL+1,preL+num,inL,i-1,bt); //左子树递归
data[bt].rchild=create(preL+num+1,preR,i+1,inR,bt); //右子树递归
}
return bt;
}
void posOrder(int bt){
//后序遍历是左右根
if(bt){
posOrder(data[bt].lchild); //左
posOrder(data[bt].rchild); //右
cout<<data[bt].value; //根
}
return;
}
int main(){
cin>>pre>>in;
n=strlen(pre);
root=create(0,n-1,0,n-1,0); //建树;
posOrder(root);
return 0;
}