Tree (Using middle order and post order to restore binary tree, pointers are not applicable)

vjudge submit link

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

Title:

Given the middle order and post order of the tree, find the shortest path from the root to the leaf (the sum of the weights on the path), and finally output the weight of the leaf node. If there are multiple shortest paths, the one with the smallest leaf node weight is output.

Problem-solving ideas:

First, use the middle order and the post order to construct a binary tree, and then use the preorder traversal to find the shortest path, and record the weight of the smallest leaf node.

Small issues that need to be noted:

  1. The number of leaf nodes is not stated. You need to use it to get bool read_list(int *a). It is not difficult to understand the things in C++.
  2. Regarding the construction of the binary tree, the lch and rch arrays are used cleverly to simulate the appearance of the binary tree, so no pointers are used.
  3. Similar operation point here

Code:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<sstream>
#include<algorithm>
using namespace std;
const int maxn=10010;
const int INF=0x3f3f3f3f;
int in_order[maxn];//存中序 
int post_order[maxn];//存后序 
int lch[maxn];//存左子树 
int rch[maxn];//存右子树 
int n;//存结点个数
//把未知个数存到数组里的简单方法 
bool read_list(int *a)
{
	string line;//先看成一个字符串 
	if(!getline(cin,line))	return false;
	stringstream ss(line);
	n=0;//切记:这里不能再次定义 
	int x;
	while(ss >> x)	a[n++]=x;//将数字分割出来 
		return n>0; 
}
int build(int l1,int r1,int l2,int r2)//递归建树,l1,r1代表中序,l2,r2代表后序 
{
	if(l1>r1)	return 0;//当左大于右时停止
	int root=post_order[r2];//后序的最后一个为根
	int  p=l1;
	while(in_order[p]!=root)	p++;//找到根的位置
	int cnt=p-l1;//因为中序的根在中间,所以减去l1后恰好算出左子树的个数
	//这里cnt非常棒,一开始真的没看懂,这里考虑一下后序遍历特点:左右根
	//根已经在中序中找到,同时呢还知道根的左边有cnt个结点,当然也可知晓右子树有几个结点(这里知道一个即可) 
	//因为我们一般习惯于利用中序遍历去左右子树,其实当我们知道左右子树个数时,利用后序遍历也是可以分左右子树的 
 
	lch[root]=build(l1,p-1,l2,l2+cnt-1);//分别中序和后序的左子树 
	rch[root]=build(p+1,r1,l2+cnt,r2-1);//分别中序和后序的右子树 
	return root;
}
int best,best_sum;
void dfs(int root,int sum)//先序:根左右 
{
	sum+=root;//求权值和
	if(!lch[root]&&!rch[root])
	{
		if(sum<best_sum||(sum==best_sum&&root<best))
		{
			best=root;
			best_sum=sum;
		}
	}
	if(lch[root])
		dfs(lch[root],sum);//左
	if(rch[root])
		dfs(rch[root],sum);//右
	return; 
}
int main()
{
	while(read_list(in_order))
	{
		read_list(post_order);
		build(0,n-1,0,n-1);
		best_sum=INF;
		dfs(post_order[n-1],0);
		printf("%d\n",best);
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/Helinshan/article/details/114548557