preorder root+left+right inorder left+root+right postorder left+right+root
给出中序和后序遍历,找出路径权重值最小的叶节点。最后输出最小路径所对应的叶节点编号。若路径权重值相等,输出叶节点最小的叶节点编号
思路:lch和rch建左右子树,build带中序和后序的左右节点,返回当前树的根节点。root左子树的更新找左子树的根节点,右子树更新同理。因节点用根节点的数组表示,找最小路径用dfs,建立变量sum更新到最后比较
#include<iostream>
#include<string>
#include<sstream>
#include<algorithm>
using namespace std;
const int maxv=10000+10;
int in_order[maxv],post_order[maxv],lch[maxv],rch[maxv];
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;//a挨个保存每列读取的整数
return n>0;
}
int build(int l1,int r1,int l2,int r2){//前两个数为in_order,后两个数为post_order
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;//root存在,build成功
}
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(void){
while(read_list(in_order)){
read_list(post_order);
build(0,n-1,0,n-1);
best_num=1000000;
dfs(post_order[n-1],0);
cout<<best<<"\n";
}
}