数据结构 uva 548-Tree

来源:互联网 发布:工业大数据挖掘 编辑:程序博客网 时间:2024/04/30 20:55

 

题目链接:

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=489

 

题目意思:

一颗二叉树用中序和后序遍历给出,让你求出从根到叶子节点的总和最小的叶子节点的值。

 

解题思路:

根据中序遍历序列和后序遍历序列,构建二叉树,然后用dfs求总和最小的那个叶子节点的值。

后序遍历的最后一个节点一定是根节点,根节点在中序中的位置之前的节点一定在这个根的左树上,根节点在中序的位置之后的节点一定在这个根的右树上。

据此可以用递归来建这个树,注意有的节点没有左孩子或右孩子。

 

代码:

#include<iostream>#include<cstdio>#define INF (1<<20)using namespace std;int inorder[11000],suborder[11000];struct Node{int value,left,right;}tree[11000];int num,Min,ans;int build(int start1,int end1,int start2,int end2)  //建立一颗二叉树{if(end1<start1||end2<start2)  //没有左孩子或右孩子return 0;tree[++num].value=suborder[end2]; //将值存入树节点中int temp=num;if(start1==end1)   //到达叶子节点{tree[num].left=-1;return num;}int i;for(i=start1;i<=end1;i++)  //遍历中序,找到当前节点的位置if(inorder[i]==suborder[end2])break;tree[temp].left=build(start1,i-1,start2,i-start1+start2-1); //建立当前节点的左树,注意不能用tree[num].left,应为num为全局变量,会改变直至最后,wa了好多次tree[temp].right=build(i+1,end1,i-start1+start2,end2-1);  //建立当前节点的右树return temp; //注意是return 当前的节点编号,wa了好几次}void DFS(int cur,int sum) //dfs求和{sum+=tree[cur].value;  if(tree[cur].left==-1)  //如果到达了叶子节点,则返回{if(sum<Min){Min=sum;ans=tree[cur].value;}return ;}if(tree[cur].left==0&&tree[cur].right!=0)  //遇到没有孩子的情况,不能全盘不做,要考虑还有另一个孩子{DFS(tree[cur].right,sum);return ;}if(tree[cur].right==0&&tree[cur].left!=0){DFS(tree[cur].left,sum);return ;}if(tree[cur].right==0&&tree[cur].left==0) //既没有做孩子又没有右孩子return;DFS(tree[cur].left,sum);  //从左孩子dfsDFS(tree[cur].right,sum); //从右孩子dfsreturn ;}int main(){char c;int len1=0,len2=0;while(scanf("%d%c",&inorder[++len1],&c)!=EOF)  //注意读入的方式{while(c!='\n')scanf("%d%c",&inorder[++len1],&c);do{scanf("%d%c",&suborder[++len2],&c);}while(c!='\n');num=0;build(1,len1,1,len2); //建树Min=INF;DFS(1,0);  //求最大的总和的叶子节点的值printf("%d\n",ans); len1=len2=0;   //注意每次清零}return 0;}


 

原创粉丝点击