UVA548——Tree(中后序建树+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:
#include<malloc.h>
#include<iostream>
#include<stdio.h>
#include<string>
#include<cstring>
using namespace std;
struct tree
{
int data;
int left;
int right;
} T[]; //数组模拟的二叉树
int m_sum=,pos; //用于DFS时保存结果
int mid[],last[];
int create_tree(int m1,int m2,int l1,int l2)
{
if (m1==m2)
{
T[m1].left=T[m1].right=-;
T[m1].data=mid[m1];
return m1;
}
if (m1>m2)
return -;
int i;
for (i=; i<=m2; i++)
if (mid[i]==last[l2]) break;
T[i].left=create_tree(m1,i-,l1,l1+i-m1-);//递归建树!!注意四个参数,runtime好多遍
T[i].right=create_tree(i+,m2,l1+i-m1,l2-);
T[i].data=mid[i];
return i;
}
int min(int a,int b)
{
return a>b?b:a;
}
int dfs(int head,int m)
{
m+=T[head].data;
if (T[head].left==-&&T[head].right==-)
{
if (m<m_sum) //打擂台,选出最小的结果,并将叶子节点的数值存入pos中
{
m_sum=m;
pos=T[head].data;
}
return T[head].data;
}
int sum=T[head].data;
if (T[head].left!=-&&T[head].right==-) sum+=dfs(T[head].left,m);
else if (T[head].right!=-&&T[head].left==-) sum+=dfs(T[head].right,m);
else sum+=min(dfs(T[head].left,m),dfs(T[head].right,m));
return sum;
}
int main()
{
int k1=,k2=;
while (scanf("%d",&mid[])!=EOF)
{
pos=,m_sum=;
k1=;
for (int i=; i<=; i++)
T[i].left=T[i].right=-,T[i].data=;
while ()
{
char ch=getchar();
if (ch=='\n') break;
scanf("%d",&mid[k1++]);
}
k1--,k2=;
while ()
{
scanf("%d",&last[k2++]);
char ch=getchar();
if (ch=='\n') break;
}
k2--;
int T_head=create_tree(,k1,,k2);
dfs(T_head,);
printf("%d\n",pos);
}
return ;
}
UVA548——Tree(中后序建树+DFS)的更多相关文章
- [C++] 非递归实现前中后序遍历二叉树
目录 前置技能 需求描述 binarytree.h 具体实现 binarytree.cpp main.cpp 网上代码一搜一大片,大同小异咯. 书上的函数实现代码甚至更胜一筹,而且抄一遍就能用,唯一问 ...
- 前中后序递归遍历树的体会 with Python
前序:跟->左->右 中序:左->根->右 后序:左>右->根 采用递归遍历时,编译器/解释器负责将递归函数调用过程压入栈并保护现场,在不同位置处理根节点即可实现不 ...
- PAT Advanced 1127 ZigZagging on a Tree (30) [中序后序建树,层序遍历]
题目 Suppose that all the keys in a binary tree are distinct positive integers. A unique binary tree c ...
- PAT甲题题解-1127. ZigZagging on a Tree (30)-中序、后序建树
根据中序遍历和前序遍历确定一棵二叉树,然后按“层次遍历”序列输出.输出规则:除根节点外,接下来每层的节点输出顺序是:先从左到右,再从右到左,交替输出 #include <iostream> ...
- Binary Tree Traversal 二叉树的前中后序遍历
[抄题]:二叉树前序遍历 [思维问题]: 不会递归.三要素:下定义.拆分问题(eg root-root.left).终止条件 [一句话思路]: 节点非空时往左移,否则新取一个点 再往右移. [输入量] ...
- POJ 2255 Tree Recovery && Ulm Local 1997 Tree Recovery (二叉树的前中后序遍历)
链接:poj.org/problem?id=2255 本文链接:http://www.cnblogs.com/Ash-ly/p/5463375.html 题意: 分别给你一个二叉树的前序遍历序列和中序 ...
- 【紫书】Tree UVA - 548 静态建树dfs
题意:给你中序后序 求某叶子节点使得从根到该节点权值和最小.若存在多个,输出其权值最小的那个. 题解:先建树,然后暴力dfs/bfs所有路径,取min 技巧:递归传参数,l1,r1,l2,r2, su ...
- 数据结构-C语言递归实现树的前中后序遍历
#include <stdio.h> #include <stdlib.h> typedef struct tree { int number ; struct tree *l ...
- 飘逸的python - 极简的二叉树前中后序通杀函数
对于任一结点.能够按某种次序运行三个操作: 訪问结点本身(N) 遍历该结点的左子树(L) 遍历该结点的右子树(R) 用来表示顺序,即,前序NLR/中序LNR/后序LRN. 以下我们用namedtupl ...
随机推荐
- 比较X与Y的大小,绝对精准!!!!!!
代码! #include<stdio.h> int max(int a,int b) { int x; x=a+b; return x; } int main() { int i,n,t; ...
- 在O(1)时间删除链表结点
题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点. 链表结点与函数的定义如下: struct ListNode { int m_nValue; ListNode* m_p ...
- Poj 2707 Copier Reduction
1.Link: http://poj.org/problem?id=2707 2.Content: Copier Reduction Time Limit: 1000MS Memory Limit ...
- Java中的分代垃圾回收策略
一.分代GC的理论基础 分代的垃圾回收策略,是基于这样一个事实:不同的对象的生命周期是不一样的.因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率. 在Java程序运行的过程中,会产生大 ...
- android SDK Manager更新不了,出现错误提示:"Failed to fetch URL..."!
可以用以下办法解决: 使用SDK Manager更新时出现问题 Failed to fetch URL https://dl-ssl.google.com/android/repository/rep ...
- GridView - javascript 触发后台 OnSelectedIndexChanged
1.ASPX <asp:GridView ID="gdvDealers" runat="server" AutoGenerateColumns=" ...
- 获取JAVA对象占用的内存大小
介绍两种获取JAVA对象内存大小的方法. 第一种:Instrumentation 简介: 使用java.lang.instrument 的Instrumentation来获取一个对象的内存大小.利用I ...
- [总结]Android系统体系结构
Android 从图中可以看出Android主要的组成部分,其中底层是Linux的内核,包括的主要就是文件.内存.系统资源等的管理,Google在这部分的工作主要就是电源管理和一部分驱动,并且整合上层 ...
- Laravel框架数据库CURD操作、连贯操作总结
这篇文章主要介绍了Laravel框架数据库CURD操作.连贯操作.链式操作总结,本文包含大量数据库操作常用方法,需要的朋友可以参考下 一.Selects 检索表中的所有行 复制代码代码如下: $use ...
- window2003安全设置
1. 网上邻居->右键 属性->本地连接 右键属性->Microsoft网络的文件和打印机共享去掉选中 (影响端口: 139,445) 2. 禁止ADMIN$缺省共享 ...