题意:
给你中序遍历序列和后序遍历序列,要你找出这棵树中从根节点到任意叶子节点的最小值中的叶子节点的值。
思路分析:
根据中序和后序遍历的序列建树(需要同时应用两个序列的信息才能进行建树)
我们需要通过后序遍历序列的最后一位来得到当前规模的子树的根节点,再利用中序遍历得到左右子树节点的规模,将当前树拆分为左右子树进行递归得到所要建立的二叉树
建完树后,只需要利用dfs按二叉树的结构进行查找就可以了
对于处理输入数据,学到了
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=1e4+10;
int in_order[maxn],post_order[maxn],l[maxn],r[maxn];
//存中序,后序遍历序列,以及该节点的左右儿子
int n,sum_max,max_node;
//学到了一种输入数据的处理方式
bool read_list(int a[])
{
string line;
//getline(cin,str)可以将空格作为字符串读入 ,并且当读到文件尾返回0
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)
{
//叶子节点的左右儿子清为0,并作为递归终点
if(l1 > r1){
return 0;
}
//后序遍历序列的最后一个数为当前树的根节点
int root = post_order[r2];
int k = l1;
//在中序1遍历序列中找到当前树跟节点位置
while(in_order[k] != root){
k++;
}
int cnt = k - l1;//左子树节点个数;
//这里是将该树拆分为根节点,左子树和右子树,来递归计算当前树的左子树和右子树的
//值
l[root] = build(l1,k - 1,l2,l2 + cnt - 1);
r[root] = build(k + 1,r1,l2 + cnt,r2 - 1);
return root;
}
void dfs(int u,int sum)
{
sum += u;
if((l[u] == 0&&r[u] == 0)&&(sum < sum_max||(sum == sum_max&&u < max_node))){
max_node = u;
sum_max = sum;
return ;
}
//左子树不为空
if(l[u]){
dfs(l[u],sum);
}
if(r[u]){
dfs(r[u],sum);
}
}
int main()
{
while(read_list(in_order)){
read_list(post_order);//读取中序和后序遍历序列
build(0,n - 1,0,n - 1);
sum_max = inf;
dfs(post_order[n - 1],0);
cout<<max_node<<endl;
}
return 0;
}