UVA - 548 - Tree (中序+后序建树+DFS)

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=489

548 - Tree

Time limit: 3.000 seconds

Problem:

You are to determine the value of the leaf node in a given binary tree that is the terminal node of a path of least value from the root of the binary tree to any leaf. The value of a path is the sum of values of nodes along that path.

Input:

The input file will contain a description of the binary tree given as the inorder and postorder traversal sequences of that tree. Your program will read two line (until end of file) from the input file. The first line will contain the sequence of values associated with an inorder traversal of the tree and the second line will contain the sequence of values associated with a postorder traversal of the tree. All values will be different, greater than zero and less than 10000. You may assume that no binary tree will have more than 10000 nodes or less than 1 node.

Output:

For each tree description you should output the value of the leaf node of a path of least value. In the case of multiple paths of least value you should pick the one with the least value on the terminal node.

Sample Input

3 2 1 4 5 7 6

3 1 2 5 6 7 4

7 8 11 3 5 16 12 18

8 3 11 7 16 18 12 5

255

255

Sample Output

1

3

255

题意:给出一棵树的中序和后序,要求你输出:根到叶子的和最小的那条路径的叶子的值

思路:1:由给出的中序和后序数组构建出树

2:DFS遍历,找出和最小的路径(标记叶子值),输出。

参考博客:https://www.cnblogs.com/Enumz/p/3840838.html

 

 1 #include<stdio.h>
 2 #include<iostream>
 3 #include<string.h>
 4 using namespace std;
 5 struct tree
 6 {
 7     int data;
 8     int left;
 9     int right;
10 }T[100100];
11 int mid[100100],last[100100];//中序,后序 
12 //左根右,左右根 
13 long long min_sum=999999999;
14 int pos=-1;
15 //m1,m2为中序对应的一段区域
16 //l1,l2为后序对应的一段区域 
17 int cread_tree(int m1,int m2,int l1,int l2)
18 {
19     if(m1==m2)//只剩一个 ,即叶子结点 
20     {
21         T[m1].left=T[m1].right=-1;
22         T[m1].data=mid[m1];
23         return m1;
24      }
25      if(m1>m2)//不存在 
26      return -1;
27      int i;
28      for(i=0;i<=m2;i++)
29      if(mid[i]==last[l2]) break;//找出根结点在中序遍历中的位置 i
30      T[i].data=mid[i];
31      T[i].left=cread_tree(m1,i-1,l1,(l1+(i-1-m1)));//左右根"左"结束的地方即为l1+(i-1-m1)
32      T[i].right=cread_tree(i+1,m2,l1+i-m1,l2-1);//因为后序"左右根",我们现在l1要的是"右"起始的部分,l2要的是"右"结束的地方(即l2-1).
33      // 哪起始的地方为啥是l1+i-m1,因为起始的地方就是上面"左"结束的地方+1, l1+(i-1-m1)+1 
34      return i;
35 }
36 int DFS(int head,int sum)
37 {
38     sum+=T[head].data;//目前从根节点到该节点的值 
39     if(T[head].left==-1&&T[head].right==-1)//如果它没有左右孩子,它就是叶子结点,则比较 
40     {
41         if(sum<min_sum)//如果路径值比之前标记的路径值小,则重新标记 
42         {
43             min_sum=sum;//重新标记 
44             pos=T[head].data;//重新标记最小路径的叶子的值 
45         }
46         return T[head].data;
47     }
48     if(T[head].left==-1&&T[head].right!=-1) DFS(T[head].right,sum);//遍历
49     else if(T[head].left!=-1&&T[head].right==-1) DFS(T[head].left,sum);//遍历
50     else//遍历
51     {
52         DFS(T[head].right,sum);
53         DFS(T[head].left,sum);
54     }
55 }
56 int main()
57 {
58     while(scanf("%d",&mid[0])!=EOF){
59         min_sum=999999999;pos=-1;//pos即为标记最小路径的叶子的值,min_sum为路径最小值 
60         for(int i=0;i<1000;i++)
61         {
62             T[i].data=0;
63             T[i].left=T[i].right=-1;
64         }
65         int k1=1;
66         while (1)//输入后面的中序 
67         {
68             char c=getchar();
69             if(c=='\n') break;
70             scanf("%d",&mid[k1++]); 
71         }
72         k1--;int k2=0;
73         while (1)//输入后序 
74         {
75             scanf("%d",&last[k2++]);
76             char c=getchar();
77             if(c=='\n') break;
78         }
79         k2--;
80         int head=cread_tree(0,k1,0,k2);//得出头(根)结点
81         DFS(head,0);//从头(根)结点开始遍历 
82         printf("%d\n",pos);
83     }
84     return 0;
85 }

 

posted @ 2018-07-30 14:42  jealous-boy  阅读(267)  评论(0编辑  收藏  举报