根据中序和后序求二叉树(算法笔记)

根据中序和后序求二叉树

题目描述:给出二叉树的中序和后序序列,输出二叉树的层序遍历序列。

题目分析:中序遍历为左根右,后序遍历为左右根,所以后序遍历的最后一个节点为根节点,在中序遍历上找出根节点的位置,将树分为左右两个子树。

使用 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;
} 
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值