UVA548——Tree(中后序建树+DFS)

本文介绍了如何通过中序和后序遍历序列构建二叉树,进而找到从根节点到叶子节点路径最短的叶子节点。通过递归构建二叉树并使用深度优先搜索(DFS)策略,最终确定了路径长度最小的叶子节点。此算法对于理解二叉树结构及其遍历方法具有重要意义。

Tree

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

题目大意:

    输入一个二叉树的中序和后序,输出一个叶子节点,该叶子节点到根的数值总和最小。

解题思路:

    先通过后序和中序建立二叉树,在通过DFS进行搜索,找到符合题目要求的叶子。(需要使用全局变量来记录DFS过程中的最小和叶子)

    中序和后序建立二叉树:

      使用递归来逐步建立,由后序连确定当前递归中的分支的根节点,再在中序中找到根的位置,则中序中根左的为左子树的中序排列,根右的为右子树的中序。设此时左子树的长度为len,则当前的后序的前len个数据是左子树的后序排列。同理进行递归即可。右子树同理。

    DFS:

      设一个变量m,每次递归时作为实参进入调用,并执行m+=tree.data,则能保证递归到叶子节点时,m保存的是当前叶子到根节点的和,根据m的大小,即可选出符合题意的叶子节点。

Code:

 1 #include<malloc.h>
 2 #include<iostream>
 3 #include<stdio.h>
 4 #include<string>
 5 #include<cstring>
 6 using namespace std;
 7 struct tree
 8 {
 9     int data;
10     int left;
11     int right;
12 } T[100100]; //数组模拟的二叉树
13 int m_sum=100000000,pos; //用于DFS时保存结果
14 int mid[100100],last[100100];
15 int create_tree(int m1,int m2,int l1,int l2)
16 {
17     if (m1==m2)
18     {
19         T[m1].left=T[m1].right=-1;
20         T[m1].data=mid[m1];
21         return m1;
22     }
23     if (m1>m2)
24         return -1;
25     int i;
26     for (i=0; i<=m2; i++)
27         if (mid[i]==last[l2]) break;
28     T[i].left=create_tree(m1,i-1,l1,l1+i-m1-1);//递归建树!!注意四个参数,runtime好多遍
29     T[i].right=create_tree(i+1,m2,l1+i-m1,l2-1);
30     T[i].data=mid[i];
31     return i;
32 }
33 int min(int a,int b)
34 {
35     return a>b?b:a;
36 }
37 int dfs(int head,int m)
38 {
39     m+=T[head].data;
40     if (T[head].left==-1&&T[head].right==-1)
41     {
42         if (m<m_sum) //打擂台,选出最小的结果,并将叶子节点的数值存入pos中
43         {
44             m_sum=m;
45             pos=T[head].data;
46         }
47         return T[head].data;
48     }
49     int sum=T[head].data;
50     if (T[head].left!=-1&&T[head].right==-1) sum+=dfs(T[head].left,m);
51     else if (T[head].right!=-1&&T[head].left==-1) sum+=dfs(T[head].right,m);
52     else sum+=min(dfs(T[head].left,m),dfs(T[head].right,m));
53     return sum;
54 }
55 int main()
56 {
57     int k1=0,k2=0;
58     while (scanf("%d",&mid[0])!=EOF)
59     {
60         pos=0,m_sum=100000000;
61         k1=1;
62         for (int i=0; i<=10000; i++)
63             T[i].left=T[i].right=-1,T[i].data=0;
64         while (1)
65         {
66             char ch=getchar();
67             if (ch=='\n') break;
68             scanf("%d",&mid[k1++]);
69         }
70         k1--,k2=0;
71         while (1)
72         {
73             scanf("%d",&last[k2++]);
74             char ch=getchar();
75             if (ch=='\n') break;
76         }
77         k2--;
78         int T_head=create_tree(0,k1,0,k2);
79         dfs(T_head,0);
80         printf("%d\n",pos);
81     }
82     return 0;
83 }

 

转载于:https://www.cnblogs.com/Enumz/p/3840838.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值