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; }
朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。