6_8二叉树的递归遍历uva548
题目
分析
根据输入的中序和后序遍历结果建树,再对该树进行深度优先遍历。后序遍历的最后一个即为根节点,在中序遍历中找到它就可以构建出树,最后递归遍历。
重点函数:
#include<sstream>
头文件包含三个类:istringstream、ostringstream、stringstream。
用到了其中的stringstream,stringstream用法:
创建一个对象,向对象输入字符串,可根据需要再输出
getline():输入一个字符串并存到line中。
源代码
#include<string>
#include<iostream>
#include<algorithm>
#include<sstream>
using namespace std;
const int MAXN = 10000+10;
int in_order[MAXN],post_order[MAXN];//存放输入的中序和后序遍历结果
int lch[MAXN],rch[MAXN];//存左右子树
int n;
//将输入的值放入数组中,并计数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){
//后序遍历的尾元素必为根元素,再在中序遍历中找到该根元素
if(L1>R1)return 0;//空树
int root = post_order[R2];
int p = L1;
while(in_order[p] != root)p++;//找到根元素在中序遍历中的索引p
int cnt = p-L1;//左子树的节点个数
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 u,int sum){
sum+=u;//将该点值加上,如果小于最优解,则替换
if(!lch[u] && !rch[u]){
if(sum <best_sum || (sum == best_sum && u<best)){best = u;best_sum = sum;}
}
if(lch[u])dfs(lch[u],sum);
if(rch[u])dfs(rch[u],sum);
}
int main(){
while(read_list(in_order)){//输入中序遍历
read_list(post_order);//输入后序遍历
build(0,n-1,0,n-1);//建树
best_sum = 100000000;
dfs(post_order[n-1],0);//后序遍历尾节点为根节点
cout<<best<<"\n";
}
return 0;
}