杭电1710题、天梯赛L2-011(由二叉树的前序、中序遍历求后序遍历)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1710

#include<bits/stdc++.h>
using namespace std;
struct node
{
	int val;  //节点的值 
	node* l;  //左子树 
	node* r;  //右子树 
};
int qx[1005]; //前序遍历 
int zx[1005]; //后序遍历 
node* build(int ql,int qr,int zl,int zr)  //建树函数 
{
	if(zl>zr)  return NULL;  //如果左边界大于右边界,结束 
	int root=qx[ql];  //前序遍历第一个就是根节点的值 
	int pos=zl;   //pos为根节点在中序遍历中的位置,初始化为中序遍历的左边界 
	while(zx[pos]!=root)  pos++; //求出根节点在中序遍历中的位置 
	int len=pos-zl;  //求出左子树的长度 
	node* rt=new node();  //申请内存 
	rt->val=root;   //存入根节点的值 
	rt->l=build(ql+1,ql+len-1,zl,pos-1);  //建立左子树 
	rt->r=build(ql+len+1,qr,pos+1,zr);   //建立右子树 
	return rt;
}
int ans;
void houxu(node* rt)  //后序遍历 
{
	if(rt==NULL)  return;  //如果节点为空,结束 
	else
	{
		houxu(rt->l);  //遍历左子树,输出值 
		houxu(rt->r);  //遍历右子树,输出值 
		if(ans==0)     //最后输出根节点的值 
		{
			ans++;
			cout<<rt->val;
		}
		else cout<<" "<<rt->val;
	}
}
int main()
{
	int n;
	node* rt;
	while(cin>>n)  //输入数组长度 
	{
		for(int i=0;i<n;i++)  cin>>qx[i];  //输入前序遍历 
		for(int i=0;i<n;i++)  cin>>zx[i];  //输入后序遍历 
		rt=build(0,n-1,0,n-1);  //建树 
		ans=0;  //标记是否是第一个输出的 
		houxu(rt);  //后序遍历输出 
		cout<<endl;
	}
    return 0;
}

天梯赛L2-011 玩转二叉树 (25 分)也是一样的,只不过输出不同,天梯赛是输出该树反转后的层序遍历的序列。
AC代码如下:

#include <bits/stdc++.h>
using namespace std;
struct node
{
	int val;  //节点的值 
	node* l;  //左子树 
	node* r;  //右子树 
}; 
int zx[35];  //中序遍历数组 
int qx[35];  //前序遍历数组 
node* build(int zl,int zr,int ql,int qr)  //建树操作 
{
	if(zl>zr)  return NULL; //如果左边界大于右边界,结束 
	int ans=qx[ql];  //前序遍历的第一个就是根节点的值 
	int pos=zl;  //初始化父节点的位置在中序遍历的左边界 
	while(zx[pos]!=ans)  pos++;  //找到父节点在中序遍历中的位置 
	int len=pos-zl;  //求出左子树的长度 
	node* rt=new node();  //申请内存 
	rt->val=ans;  //存父节点的值 
	rt->l=build(zl,pos-1,ql+1,ql+len-1);  //建立左子树 
	rt->r=build(pos+1,zr,ql+len+1,qr);  //建立右子树 
	return rt;  //又是这错了,一定要返回根节点 
}
bool flag;
void cengci(node* rt)  //镜像翻转的层次遍历 
{
	int ans;
	queue<node*>q;
	while(!q.empty())  q.pop();
	if(rt!=NULL) q.push(rt);  //根节点不为空,存父节点 
	while(!q.empty())  
	{ 
		rt=q.front();  //取出父节点 
		q.pop();   //将父节点从队列中删除 
		ans=rt->val;  
		if(flag)   //输出父节点的值 
		{
			flag=false;
			cout<<ans;
		}
		else cout<<" "<<ans; 
		if(rt->r!=NULL)  q.push(rt->r);  //将右子树压入队列 
		if(rt->l!=NULL)  q.push(rt->l);  //将左子树压入队列 
	}
}
int main()
{
	node* rt;
	int n;
	while(cin>>n)
	{
		for(int i=0;i<n;i++)  cin>>zx[i];  //输入前序遍历 
		for(int i=0;i<n;i++)  cin>>qx[i];  //输入中序遍历 
		rt=build(0,n-1,0,n-1);  //建树 
		flag=true;
		cengci(rt);  //翻转后的层次遍历 
		cout<<endl;
	}
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值