hdu1710(二叉树的历遍)

http://acm.hdu.edu.cn/showproblem.php?pid=1710

题意:依次给出二叉树的前序历遍和中序历遍,要你输出它的后序历遍。

感叹:这个题目,我不得不感慨用递归解决二叉树的问题真心碉堡了。也不得不感叹,自己还是太水了,记得以前我的一个学长做这个题目,没超过十分钟后就ac了。

思路:用递归做的宏观思路很简单,就是结合前序历遍和中序历遍,找根节点,在中序历遍中,根节点左边的全部是左子树,右边的全部是右子树,那么将这些结点慢慢划分为一个个子问题。左子树的第一个结点又可以看作一个新的根节点,它有它的左子树和右子树,同理,慢慢划分,递归的思路也就出来了。假如中序历遍中第i个点是根节点,那么划分为两个区域,0~i和i~n-1;

#include<iostream>
using namespace std;
typedef struct tree
{
	tree *l,*r;
	int num;
}tree;
tree *root;
tree *creat(int *a,int *b,int n)                       //建树
{
	tree *ss;
	for(int i=0;i<n;i++)
	{
		if(a[0]==b[i])                           //当在中序历遍中找到了根节点后
		{
			ss=(tree *)malloc(sizeof(tree));
			ss->num=b[i];
			ss->l=creat(a+1,b,i);               //中序历遍中在根节点左边的都是左子树上的
			ss->r=creat(a+i+1,b+i+1,n-i-1);    //在根节点右边的,都是右子树上的,右子树需要从i+1开始
			return ss;
		}
	}
	return NULL;                             //没有找到的,返回NULL
}
void libian(tree *h)                    //后序历遍
{
	if(h!=NULL)
	{
		libian(h->l);
		libian(h->r);
		if(h==root)                     //后序历遍最后历遍根节点
			printf("%d\n",h->num);
		else
			printf("%d ",h->num);
	}
}
int main()
{
	int n;
	while(scanf("%d",&n)>0)
	{
		root=NULL;
		int a[2000],b[2000],i;
		for(i=0;i<n;i++)
		{
			scanf("%d",&a[i]);
		}
		for(i=0;i<n;i++)
		{
			scanf("%d",&b[i]);
		}
		root=creat(a,b,n);
		tree *h=root;
		libian(h);
	}
	return 0;
}

 

 

posted @ 2013-01-13 15:17  紫忆  阅读(2554)  评论(0编辑  收藏  举报