根据中序和后序求二叉树
题目描述:给出二叉树的中序和后序序列,输出二叉树的层序遍历序列。
题目分析:中序遍历为左根右,后序遍历为左右根,所以后序遍历的最后一个节点为根节点,在中序遍历上找出根节点的位置,将树分为左右两个子树。
使用 in[],post[] 存储中序后后序序列。假设某个分支二叉树中序区间为[inL, inR],后序区间为[postL,postR],那么post[postR]就为该树的根节点,根据根节点去中序中查找,找到根节点在中序中的位置为k。二叉树左子树的个数为numLeft=k-inL。左子树的中序区间为[inL,k-1],右子树的中序区间[k+1,inR];左子树的后序区间为[postL,postL+numLeft-1],右子树的后序区间为[postL+numLeft,postR-1]。
创建树时返回根节点的地址。最后层序遍历树,使用队列,从根节点开始,将节点入队,然后读队首,再出队直至队列为空。
运行结果:
代码如下:
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn=50;
// 定义树
struct node{
int data;
node* lchild;
node* rchild;
};
int in[maxn],post[maxn]; //定义前中后序数组
int n; // 节点个数
// 返回node类型的根节点地址
node* create(int postL, int postR, int inL, int inR){
if(postL > postR){ //
return NULL;
}
node* root=new node; //新建一个节点,存放根节点
root->data=post[postR];
int k;
for(k=inL;k<=inR;k++){ //中序中找到k的值
if(in[k]==post[postR]){
break;
}
}
int numLeft=k-inL; //左子树的节点个数
root->lchild= create(postL, postL+numLeft-1, inL,k-1);
root->rchild= create(postL+numLeft, postR-1, k+1,inR);
return root;
}
int num=0;
// 层序遍历
void BFS(node* root){
queue<node*> q; //队列存的node类型的地址
q.push(root); //根节点入队
while(!q.empty()){
// 取出队首元素并访问
node* now=q.front();
q.pop();
cout<<now->data;
num++;
if(num<n)cout<<" ";
if(now->lchild!=NULL) q.push(now->lchild);
if(now->rchild!=NULL) q.push(now->rchild);
}
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
int x;
cin>>x;
post[i]=x;
}
for(int i=0;i<n;i++){
int x;
cin>>x;
in[i]=x;
}
node* root=create(0,n-1,0,n-1);
BFS(root);
return 0;
}