文章目录
1 UVA_树 Tree
1.1 题目描述
1.2 输入格式
1.3 输出格式
1.4 题面翻译
输入一个二叉树的中序和后序遍历,请你输出一个叶子节点,该叶子节点到根的数值总和最小,且这个叶子是编号最小的那个。
-
输入
您的程序将从输入文件中读取两行(直到文件结尾)。第一行是树的中序遍历值序列,第二行是树的后序遍历值序列。所有值将不同,大于零且小于或等于10000.二叉树的节1<=N<=10000。
-
输出
对于每个树描述,您应该输出最小值路径的叶节点的值。存在多路径最小的情况下,您应该选择终端叶子节点上具有最小值的那条路径,且输出那个最小值的终端叶子。
1.5 样例
1.5.1 样例输入
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
1.5.2 样例输出
1
3
255
1.5.3 示例
如第一个样例
3 2 1 4 5 7 6
3 1 2 5 6 7 4
构建出树
将一条路上的结点分别相加
4+2+3=9
4+2+1=7
4+7+5=16
4+7+6=17
由此可见,当最后叶子结点为1
时,结果最小
因此输出1
1.6 思路
分为3步
- 读取数据
- 构建树
- 查找最小值
1.6.1 读取数据
测试样例中,第一行是树的中序遍历值序列,第二行是树的后序遍历值序列。
- 传入后序或中序数组
- 直接读取每一行
- 而每行数据的每个数字,中间都有一个空格,这里我们不再使用string来存储,而使用
stringstream
字符串流将读取到的一整行存入缓冲区中 - 然后重定向缓冲区,每次读取一个整型
int
的数据,将读取到的一个整型按下标存入原数组
实现
bool ReadLine(int* val)
{
string line;
if (!getline(cin, line)) return false;
stringstream str(line); //将读取到的line一个字符串流的缓冲区str中
num = 0;
int _int;
while (str >> _int) //从str缓冲区中读数,每次读一个int
val[num++] = _int; //将读取到的int存入val数组中
return num > 0;
}
1.6.2 构建树
和前序同样的方法
实现
int CreateTree(int len1, int len2, int _num)
{
if (_num <= 0) return 0;
int root = postorder[len2 + _num - 1];
int len = 0;
while (inorder[len1 + len] != root) //计算左子树长度
len++;
left_child[root] = CreateTree(len1, len2, len);
right_child[root] = CreateTree(len1 + len + 1, len2 + len, _num - len - 1);
return root;
}
1.6.3 找最小值
- 遍历树,结点数值一直往下加
- 如果有左右节点,不断往下遍历
- 如果某个值的左右子树都为空,说明是叶子节点,即最下面的结点,此时可以将该最小值
min_val
和这条路总和min_sum
保存 - 如果某条路上的总和和其他路相同,则输出这两个最小值中的较小值
实现
void FindMin(int _val, int _sum)
{
_sum += _val;
if (!left_child[_val] && !right_child[_val]) //下面没有数据,说明是叶子节点
{
if (_sum < min_sum || (_sum == min_sum && _val < min_val))
{
min_val = _val;
min_sum = _sum;
}
}
if (left_child[_val]) FindMin(left_child[_val], _sum); //结点有左子树
if (right_child[_val]) FindMin(right_child[_val], _sum); //结点有右子树
}
1.6.4 main
#include<iostream>
#include<fstream>
#include<sstream>
using namespace std;
const int maxn = 1000 ;
int inorder[maxn], postorder[maxn], left_child[maxn], right_child[maxn];
int num, min_val, min_sum;
int main()
{
while (ReadLine(inorder))//读取中序
{
ReadLine(postorder); //读取后序
CreateTree(0, 0, num);
min_sum = 0x7fffffff;
FindMin(postorder[num - 1], 0);
cout << min_val << endl;
}
return 0;
}
取中序
{
ReadLine(postorder); //读取后序
CreateTree(0, 0, num);
min_sum = 0x7fffffff;
FindMin(postorder[num - 1], 0);
cout << min_val << endl;
}
return 0;
}