构建二叉树的两种方式(前+中) (中+后),递归

两种构建方式的区别:

1.利用中序遍历和后序遍历构建二叉树,最先建立的是 右子树,接着是左子树,

   后序遍历中根节点是最后一个元素

2.利用前序遍历和中序遍历构建二叉树,最先建立的是 左子树,接着才是右子树,

   前序遍历中根节点在第一个元素

用递归来构建树,建立左右树的顺序不同,遍历数组的起始点,方向也不同。

1.利用中序遍历和后序遍历构建二叉树

  在last[]中找到根节点,再在in[]中找到根节点的位置i,在in[i+1,end]中找右子女,在in[first,i-1]中找左子女,一直递归直到找到叶子结点为止...

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
struct node
{
	int data;
	node *l,*r;
	node (){
		l=NULL;
		r=NULL;
	}
};
int last[30];
int in[30];
int cnt;//后序遍历数组的位置 
node *create(node *root,int first,int end) // 根据前序遍历和中序遍历递归创建树 
{
	root=new node(); //为暂时的根结点创建一个实例对象,默认左右子女为空 
	root->data=last[cnt--];//根节点的值等于后序遍历的最后一个值 
	int i;
	for(i=first;i<=end;i++) //在中序遍历的数组中寻找根节点的位置 
	{
		if(in[i]==root->data){//在中序遍历中找到结点就弹出 
			break;
		}
	}
	if(i<end){ //如果根节点的右边还有数据,先构建右子树 
		root->r=create(root->r,i+1,end);
	}
	if(i>first){//如果根节点的左边还有数据,先构建左子树 
		root->l=create(root->l,first,i-1);
	}
	return root; 
}
void sequence(node *root)//层次遍历 
{
	int num=0; //记录结点个数 
	if(!root){
		return;
	}
	queue<node *>v;//存放左右结点的队列 
	v.push(root);//先把根结点放在队列中 
	num++;//结点个数+1 
	node *tmp; //临时结点  
	while(!v.empty()) //当队列中还存在未输出的结点 
	{
		tmp=v.front();//得到第一个结点 
		v.pop();//弹出 
		if(num>1){  //从第二个结点开始,前面输出一个空格隔开(题目规定) 
			printf(" "); 
		} 
		printf("%d",tmp->data);
		if(tmp->l){      //如果左子女存在,左子女进队列 
			v.push(tmp->l);
		}
		if(tmp->r){//如果右子女存在,右子女进队列 
			v.push(tmp->r);
		}
		num++;//结点个数加1 
	}
	printf("\n"); //最后换行 
}
int main()
{
	int n;
	scanf("%d",&n);//输入结点个数
	int i;
	for(i=0;i<n;i++) //输入后序遍历结果 
	{
		scanf("%d",&last[i]);
	}
	for(i=0;i<n;i++)//输入中序遍历结果 
	{
		scanf("%d",&in[i]);
	}
	cnt=n-1;
	node *root=create(root,0,n-1);//用create创建树,并返回树的根节点
	printf("利用后序和中序构建二叉树,层次遍历结果:\n"); 
	sequence(root);//遍历输出
	return 0;
}

输入输出实例,以及运行结果:


2.利用前序遍历和中序遍历构建二叉树,只需要改变上述代码cnt ,初始cnt=0,然后cnt++, 以及调整构建左右树的顺序 即可,想想然后自己码一下吧。







  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值