说说:
做了这么久,终于做到树了。先说下题意,题目给出了两组数,分别是对一棵树的中序遍历和后序遍历。然后要求的是到达根节点的路径和最短的叶子的值。所谓的路径和就是从叶子到根的路径上所有节点的值的和。这无非就是个树的遍历的问题啦。后序序列的最后一个值为子树根,然后再中序序列中找到该节点,然后树就被分成两棵子树了。然后再递归操作就可以了。这里有一点提醒一下,虽然在开始的时候,对于同一棵树,中序序列和后序序列的起始点都是相同的。但随着不断递归深入,同一棵子树的中序序列和后序序列的各自的起始位置是不同的,因此有必要给递归函数传递四个参数,分别为该子树的中序序列起始点和后序序列起始点。具体操作,看源代码好了。
源代码:
#include <stdio.h> #define MAXN 10000+5 int post[MAXN]; int in[MAXN]; int min,sum,leaf; void fun(int,int,int,int); int main(){ char c; int val,n,i; // freopen("data","r",stdin); while(1){ n=0; while(scanf("%d%c",&val,&c)&&c!='\n') in[n++]=val; in[n++]=val; n=0; while(scanf("%d%c",&val,&c)&&c!='\n') post[n++]=val; post[n++]=val; sum=0; min=10000000;//初始最小值设置得尽量大 fun(0,n-1,0,n-1); printf("%d\n",leaf); if((c=getchar())==EOF) break; else ungetc(c,stdin); } return 0; } void fun(int pbeg,int pend,int ibeg,int iend){ int i,num,root; int temp=sum; sum+=post[pend]; if(pbeg==pend){//子树仅剩一个节点,到达叶子 if(sum<min){ min=sum; leaf=post[pend]; sum=temp; } else if(sum==min&&post[pend]<leaf) leaf=post[pend]; return ; } for(num=-1,i=ibeg;i<=iend;i++,num++)//找到树根在中序序列的位置,num=左子树节点的个数-1 if(in[i]==post[pend]){ root=i; break; } if(root-1>=ibeg)//左子树非空 fun(pbeg,pbeg+num,ibeg,root-1); if(root+1<=iend)//右子树非空 fun(pbeg+num+1,pend-1,root+1,iend); sum=temp;//注意要回溯 }
原文地址:http://blog.csdn.net/u011915301/article/details/39121991