給出一棵二叉樹的中序與後序排列。求出它的先序排列。(約定樹結點用不一樣的大寫字母表示,長度<=8)。html
輸入格式:ios
2行,均爲大寫字母組成的字符串,表示一棵二叉樹的中序與後序排列。ide
輸出格式:spa
1行,表示一棵二叉樹的先序。3d
輸入樣例#1: code
BADChtm
BDCAblog
輸出樣例#1: 遞歸
ABCDip
noip2001普及組第三題
------------------------------------------------------------------------------------------------------------------------------------------------------------------
普及一下遍歷:http://www.javashuo.com/article/p-qspvryha-dr.html
講解:
首前後序遍歷有一個性質,後序遍歷的最後一個就是根。又由於題目約定樹結點用不一樣的大寫字母表示,因此對於兩個遍歷,找到後序遍歷的最後一個(就是根),在中序遍歷中找到這個字母把中序遍歷分紅兩段。那麼後續遍歷怎麼辦?中序遍歷前半段的個數,就是後序遍歷的前半段。這個過程用遞歸實現,先序遍歷在遞歸中天然就完成了。示例:
中序ACGDBHZKX,後序CDGAHXKZB,
首先可找到主根B;那麼咱們找到中序遍歷中的B,由這種遍歷的性質,
可將中序遍歷分爲ACGD和HZKX兩棵子樹,
那麼對應可找到後序遍歷CDGA和HXKZ
從而問題就變成求1.中序遍歷ACGD,後序遍歷CDGA的樹
代碼實現:
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; int book[28],len,cnt; char ans[10],a[10],b[10]; void ff(int l1,int r1,int l2,int r2) { if(l2==r2) return; ans[cnt++]=b[r2-1]; if(l2==r2-1) return; int k=book[b[r2-1]-'A']; ff(l1,k,l2,(k-l1)+l2); ff(k+1,r1,r2-1-(r1-k-1),r2-1);//琢磨琢磨吧 return; } int main() { int i,j; scanf("%s%s",&a,&b); len=strlen(a); for(i=0;i<len;i++) book[a[i]-'A']=i;//方便尋找 ff(0,len,0,len);//左閉右開的區間 for(i=0;i<cnt;i++) cout<<ans[i]; return 0; }