说说:
做了这么久,终于做到树了。先说下题意,题目给出了两组数,分别是对一棵树的中序遍历和后序遍历。然后要求的是到达根节点的路径和最短的叶子的值。所谓的路径和就是从叶子到根的路径上所有节点的值的和。这无非就是个树的遍历的问题啦。后序序列的最后一个值为子树根,然后再中序序列中找到该节点,然后树就被分成两棵子树了。然后再递归操作就可以了。这里有一点提醒一下,虽然在开始的时候,对于同一棵树,中序序列和后序序列的起始点都是相同的。但随着不断递归深入,同一棵子树的中序序列和后序序列的各自的起始位置是不同的,因此有必要给递归函数传递四个参数,分别为该子树的中序序列起始点和后序序列起始点。具体操作,看源代码好了。
源代码:
#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