树的建立(二叉树)

3 篇文章 1 订阅
1 篇文章 0 订阅

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

#include <iostream>
#include <sstream>
#include <vector>
#define _  ios_base::sync_with_stdio(0),cin.tie(0)
using namespace std;
const int maxn=1e4+5;//复用 
const int INF=0x7fffffff;
struct TreeNode{
	int left=-1;
	int right=-1;
}tree[maxn];
vector<int>in;
vector<int>post;
int build(int inL,int inR,int postL,int postR){
	if(inL>inR)//越界情况 ,不需要构建 
	return -1;
	int root=post[postR];//取当前序列的最后的值即为树(子树)根 
	int k;//中序序列中的根对应的下标 
	//in   inL  k-1  k  k+1 inR
	//leftNum = k-inL 
	//postL  postL+leftNum-1  postL+leftNum   postR-1  postR
 	for(int i=inL;i<=inR;i++){//找中序序列中的根对应的下标 
		if(root==in[i]){
			k=i;
			break;
		}
	}
	int leftNum=k-inL;//根据中序序列找到左子树节点的个数 
	tree[root].left=build(inL,k-1,postL,postL+leftNum-1);//递归构建左子树 
	tree[root].right=build(k+1,inR,postL+leftNum,postR-1);//递归构建右子树 
	return root;//返回构建完左右子树的根 
}
//void preOrderPrint(int root){
//	
//	if(~tree[root].left){
//		preOrderPrint(tree[root].left);
//	}
//	if(~tree[root].right){
//		preOrderPrint(tree[root].right);
//	}cout<<root<<" ";
//}
int sum=INF;//最短路===>路径上所有的点和最小 
int minLeaf=INF;//最小值路的最小叶子节点 
void dfs(int root,int tempSum=0){

	tempSum+=root;//求临时路径的值,存在“回溯复原状态,递归改变状态”的行为   
	if(tempSum>sum){ 
		return ; 
	} //剪枝 如果临时路径的值已经大于当前路径的值,则无需多言 
	if(!(~tree[root].left)&&!(~tree[root].right)){
		//!(~tree[root].left)成立代表,无左子树
		// !(~tree[root].right)成立代表,无右子树
		if( sum>tempSum || (minLeaf>root&&sum==tempSum)){ 
			//1\当前最短路(走到叶子节点)的值小于假设的最短路的值(tempSum) 
			//  ||
			//2\当前最短路(走到叶子节点)的值等于假设的最短路的值(tempSum)
			//且假设的最小的叶子节点值(minLeaf)大于当前的叶子节点
			//满足以上两点之一,即代表需要更新  
			sum=tempSum;
			minLeaf=root;
		}
	}
	if(~tree[root].left)//递归查找左子树 
		dfs(tree[root].left,tempSum);
	if(~tree[root].right)//递归查找左子树 
		dfs(tree[root].right,tempSum);
}
int main(){
	stringstream ss;//构建输入流ss 
	string a,b;//a==>in  b==>post 
	while(getline(cin,a)&&getline(cin,b)){//读入两个一整行包括空格的字符串 
		ss.clear(); //输入流清空   
		in.clear();//中序序列清空 
		post.clear();//后序序列清空 
		ss.str(a);//传入一个字符串,构建字符串流 
		int x;//临时变量,用来存放被空格分隔的数字 
		while(ss>>x){
			in.push_back(x);//读入中序序列 
		}
		ss.clear(); //输入流清空   
		ss.str(b);//传入一个字符串,构建字符串流 
		while(ss>>x){
			post.push_back(x);//读入后序序列
		}
		build(0,in.size()-1,0,post.size()-1);//用中序和后序构建树 
		//求最小,所以初值置为INF无穷大  无穷小-INF 
		sum=INF;//最短路===>路径上所有的点和最小 
		minLeaf=INF;//最小的叶子节点值 

		dfs(post[post.size()-1]);//深搜求值(最小叶子节点的值) 
		cout<<minLeaf<<endl;//输出结果 
	}

	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值