题意:给一棵点带权的二叉树的中序和后序遍历,找一个叶子使得他到根的路径上的权值的和最小,如果多解,那该叶子本身的权值应该最小
解题思路:1.用getline()输入整行字符,然后用stringstream获得字符串中的数字 2.用数组in_oder[]和post_order[]分别表示中序遍历和后序遍历的顺序,用数组rch[]和lch[]分别表示结点的左子树和右子树 3.用递归的办法根据遍历的结果还原二叉树(后序遍历的最后一个树表示的是根节点,中序遍历的中间一个表示根节点) 4.二叉树构造完成后,再执行一次递归遍历找出最优解
代码如下:
1 #include<stdio.h> //用数组存储二叉树 2 #include<string> 3 #include<sstream> 4 #include<iostream> 5 using namespace std; 6 const int MAXX=10100; 7 int in_order[MAXX],post_order[MAXX],lch[MAXX],rch[MAXX]; 8 int n; 9 10 bool read_list(int *a){ 11 string line ; 12 if(!getline(cin,line)) return false; 13 stringstream ss(line); 14 n=0; 15 int x; 16 while(ss>>x) a[n++]=x; 17 return n>0; 18 } 19 20 //把in_order[L1...R1]和post_order[L2...R2]建成一棵树,返回树根 21 //递归建立二叉树,数组存储左右结点 22 int build(int L1,int R1,int L2,int R2){ 23 if(L1>R1) return 0; 24 int root=post_order[R2]; 25 int p=L1; 26 while(in_order[p]!=root)p++; 27 int cnt=p-L1;//左子树的结点树 28 lch[root]=build(L1,p-1,L2,L2+cnt-1); 29 rch[root]=build(p+1,R1,L2+cnt,R2-1); 30 return root; 31 } 32 33 int best,best_sum;//目前对应的最优解和权值的和 34 35 void dfs(int u,int sum){ 36 sum=sum+u; 37 if(!lch[u]&&!rch[u]){ 38 if(sum<best_sum||(sum==best_sum&&u<best)){ 39 best=u; 40 best_sum=sum; 41 } 42 } 43 if(lch[u]) dfs(lch[u],sum); 44 if(rch[u]) dfs(rch[u],sum); 45 } 46 47 int main(){ 48 freopen("in.txt","r",stdin); 49 while(read_list(in_order)){ 50 read_list(post_order); 51 build(0,n-1,0,n-1); 52 best_sum=1e9; 53 dfs(post_order[n-1],0); 54 printf("%d ",best); 55 } 56 }
此题中二叉树的应用,比如用中序遍历和后序遍历构造出原来的二叉树,还有递归的遍历二叉树,以没有子树为递归跳出的条件