6 8 tree_uva58 - nuaazdh/acm GitHub Wiki
##例题6-7 树(Tree UVa457) ###问题
给定一个带权值的二叉树,找出一个叶子结点,使得从根节点到该结点路径上的所有结点的权值之和最小。如果存在多个这样的结点,要求结点本身的值最小。 二叉树的以中序遍历 和 后序遍历顺序给定。
样例输入
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
3
255
###分析 首先可以根据中序遍历和先序遍历的结果,建立起二叉树。然后找到每个叶子结点的路径权值,从根节点出发,当前结点的权值等于父节点权值与自身权值之和。
###code in C++
#include <iostream>
#include <vector>
#include <sstream>
const int max_size = 10100;
int inorder[max_size];
int postorder[max_size];
int min_path, min_node;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) { }
};
TreeNode *build_tree(int in_beg, int in_end, int post_beg, int pos_end) {
if (in_end < in_beg || pos_end < post_beg || (pos_end - post_beg != in_end - in_beg))
return NULL;
TreeNode *root = new TreeNode(postorder[pos_end]);
int root_pos = in_beg;
while (inorder[root_pos] != postorder[pos_end] && root_pos <= in_end) ++root_pos;
if (root_pos > in_end)
return root;
root->left = build_tree(in_beg, root_pos - 1, post_beg, post_beg + (root_pos - in_beg) - 1);
root->right = build_tree(root_pos + 1, in_end, pos_end - (in_end - root_pos), pos_end - 1);
return root;
}
void find_min_path(TreeNode *root, int parent) {
if (!root)
return;
if (!(root->left || root->right)) {
if (min_node == 0) {
min_node = root->val;
}
if (parent + root->val < min_path) {
min_path = parent + root->val;
min_node = root->val;
} else if (parent + root->val == min_path && min_node > root->val) {
min_node = root->val;
}
}
find_min_path(root->left, parent + root->val);
find_min_path(root->right, parent + root->val);
}
void free_root(TreeNode *root) {
if (!root)
return;
if (!(root->left || root->right)) {
delete root;
root = NULL;
}
if(root->left) free_root(root->left);
if(root->right) free_root(root->right);
delete root;
root = NULL;
}
int main() {
std::string line;
while (std::getline(std::cin, line)) {
min_path = 0, min_node = 0;
std::stringstream ss(line);
int i = 0;
while (ss >> inorder[i]) { min_path += inorder[i], ++i; }
std::getline(std::cin, line);
std::stringstream ss2(line);
i = 0;
while (ss2 >> postorder[i]) ++i;
TreeNode *root = build_tree(0, i - 1, 0, i - 1);
find_min_path(root, 0);
std::cout << min_node << std::endl;
free_root(root);
}
}
###点评 一个比较直观的实现,主要注意几点:
- 递归建立二叉树时,对越界判断;
- 注意审题,一个结点的路径权值和,需要加上自身结点的值;