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;

}

 

 

你可能感兴趣的:(二叉树)