題意:給一棵點帶權的二叉樹的中序和後序遍歷,找一個葉子使得他到根的路徑上的權值的和最小,如果多解,那該葉子本身的權值應該最小
解題思路:1.用getline()輸入整行字元,然後用stringstream獲得字串中的數字 2.用陣列in_oder[]和post_order[]分別表示中序遍歷和後序遍歷的順序,用陣列rch[]和lch[]分別表示結點的左子樹和右子樹 3.用遞迴的辦法根據遍歷的結果還原二叉樹(後序遍歷的最後一個樹表示的是根節點,中序遍歷的中間一個表示根節點) 4.二叉樹構造完成後,再執行一次遞迴遍歷找出最優解
程式碼如下:
#include<stdio.h> //用陣列儲存二叉樹
#include<string>
#include<sstream>
#include<iostream>
using namespace std;
const int MAXX=;
int in_order[MAXX],post_order[MAXX],lch[MAXX],rch[MAXX];
int n; bool read_list(int *a){
string line ;
if(!getline(cin,line)) return false;
stringstream ss(line);
n=;
int x;
while(ss>>x) a[n++]=x;
return n>;
} //把in_order[L1...R1]和post_order[L2...R2]建成一棵樹,返回樹根
//遞迴建立二叉樹,陣列儲存左右結點
int build(int L1,int R1,int L2,int R2){
if(L1>R1) return ;
int root=post_order[R2];
int p=L1;
while(in_order[p]!=root)p++;
int cnt=p-L1;//左子樹的結點樹
lch[root]=build(L1,p-,L2,L2+cnt-);
rch[root]=build(p+,R1,L2+cnt,R2-);
return root;
} int best,best_sum;//目前對應的最優解和權值的和 void dfs(int u,int sum){
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(){
freopen("in.txt","r",stdin);
while(read_list(in_order)){
read_list(post_order);
build(,n-,,n-);
best_sum=1e9;
dfs(post_order[n-],);
printf("%d\n",best);
}
}
此題中二叉樹的應用,比如用中序遍歷和後序遍歷構造出原來的二叉樹,還有遞迴的遍歷二叉樹,以沒有子樹為遞迴跳出的條件