UVa 548 Tree

来源:互联网 发布:在淘宝上做充值有用吗 编辑:程序博客网 时间:2024/06/13 23:06


  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 63 1 2 5 6 7 47 8 11 3 5 16 12 188 3 11 7 16 18 12 5255255

Sample Output 

13255



Miguel A. Revilla 
1999-01-11


#include <cstdio>#include <string>#include <iostream>#include <sstream>#include <vector>#include <cstdlib>#include <cstring>using namespace std;typedef struct tree_node{int val;struct tree_node* left_child;struct tree_node* right_child;}tree_node;vector<int> inorder;vector<int> postorder;tree_node* root = NULL;tree_node* gen_tree(int begin1, int end1, int begin2, int end2);void print_tree(tree_node* p);void cal_sum(int pre_sum, tree_node* p);void delete_tree(tree_node* p);// 记录最小路径上的和以及叶子节点的值int min_sum = -1;int min_value = -1;int main(){string str1, str2;while(getline(cin, str1) && getline(cin, str2)){//cout << "str1: " << str1 << endl;//cout << "str2: " << str2 << endl;stringstream scin1(str1);stringstream scin2(str2);inorder = vector<int>();postorder = vector<int>();min_sum = -1;min_value = -1;int x1, x2;while(scin1 >> x1 && scin2 >> x2){inorder.push_back(x1);postorder.push_back(x2);}//printf("gen\n");// 生成树root = gen_tree(0, inorder.size()-1, 0, postorder.size()-1);// 计算各个路径的和,得到结果cal_sum(0, root);printf("%d\n", min_value);// 收回内存//delete_tree(root);/*printf("my_tree:\n");print_tree(root);*/}return 0;}// 生成树// begin1,end1为中序串起始,结束位置// begin2,end2为后序串起始,结束位置tree_node* gen_tree(int begin1, int end1, int begin2, int end2){// 给根赋值tree_node* p = (tree_node*)malloc(sizeof(tree_node));memset(p, 0, sizeof(p));p->val = postorder[end2];p->left_child = NULL;p->right_child = NULL;// 找到左右子树的分割位置int i;for(i = begin1; i <= end1; i++){if(inorder[i] == postorder[end2])break;}// 生成左右子树if(begin1 <= i-1)p->left_child = gen_tree(begin1, i-1, begin2, begin2+(i-begin1-1));if(end1 >= i+1)p->right_child = gen_tree(i+1, end1,  end2-1-(end1-i-1), end2-1);return p;}// 遍历树void print_tree(tree_node* p){printf("%d ", p->val);if(p->left_child != NULL)print_tree(p->left_child);if(p->right_child != NULL)print_tree(p->right_child);if(p == root)printf("\n");}// 计算各个路径上的和void cal_sum(int pre_sum, tree_node* p){int now_sum = pre_sum + p->val;// 分别计算左右子树的路径和if(p->left_child != NULL)cal_sum(now_sum, p->left_child);if(p->right_child != NULL)cal_sum(now_sum, p->right_child);// 如果是叶子节点if(p->left_child == NULL && p->right_child == NULL){if(min_sum == -1 || min_sum > now_sum || (min_sum == now_sum && min_value > p->val)){min_sum = now_sum;min_value = p->val;}}}// 收回内存void delete_tree(tree_node* p){if(p->left_child != NULL)delete_tree(p->left_child);if(p->right_child != NULL)delete_tree(p->right_child);free(p);}

一道模拟题,一开始运行错误RE了好几次,以为是内存不够了,后来发现是gen_tree中
// 给根赋值tree_node* p = (tree_node*)malloc(sizeof(tree_node));memset(p, 0, sizeof(p));p->val = postorder[end2];p->left_child = NULL;p->right_child = NULL;
一开始因为有memset,就没有写
p->left_child = NULL;p->right_child = NULL;
发现加上这两句就通过了,不知为何。
0 0
原创粉丝点击