- 題目描述:
-
二叉樹的前序、中序、后序遍歷的定義:
前序遍歷:對任一子樹,先訪問跟,然后遍歷其左子樹,最后遍歷其右子樹;
中序遍歷:對任一子樹,先遍歷其左子樹,然后訪問根,最后遍歷其右子樹;
后序遍歷:對任一子樹,先遍歷其左子樹,然后遍歷其右子樹,最后訪問根。
給定一棵二叉樹的前序遍歷和中序遍歷,求其后序遍歷(提示:給定前序遍歷與中序遍歷能夠唯一確定后序遍歷)。
- 輸入:
-
兩個字符串,其長度n均小於等於26。
第一行為前序遍歷,第二行為中序遍歷。
二叉樹中的結點名稱以大寫字母表示:A,B,C....最多26個結點。
- 輸出:
-
輸入樣例可能有多組,對於每組測試樣例,
輸出一行,為后序遍歷的字符串。
- 樣例輸入:
-
ABC BAC FDXEAG XDEFAG
- 樣例輸出:
-
BCA XEDGAF
已知二叉樹的前序遍歷與中序遍歷,求后續遍歷。
前序遍歷方式為:根節點->左子樹->右子樹
中序遍歷方式為:左子樹->根節點->右子樹
后序遍歷方式為:左子樹->右子樹->根節點
從這里可以看出,前序遍歷的第一個值就是根節點,然后再中序遍歷中找到這個值,那么這個值的左邊部分即為當前二叉樹的左子樹部分前序遍歷結果,這個值的右邊部分即為當前二叉樹的右子樹部分前序遍歷結果。因此,通過這個分析,可以恢復這棵二叉樹,得到這樣的一段偽碼:
節點 getRoot(前序,中序)
c=前序第一個字符
pos=c在中序中的位置
len1=中序pos左半部分長度
len2=中序pos右半部分長度
新建節點r,令r的元素等於c
r的左兒子=getRoot(前序位置1開始的len1長度部分,中序pos位置的左半部分)
r的右兒子=getRoot(前序位置len1開始右半部分,中序pos位置的右半部分)
return r
#include <iostream> using namespace std; struct node{ char v; node *left; node *right; node(char c){ v = c; left = NULL; right = NULL; } }; string A,B; char genTree(node *t,string a,string b){ int mid=1; string la,lb,ra,rb; if(a.length()>0){ if(b.find(a[0])!=string::npos){ mid = b.find(a[0]); } lb = b.substr(0,mid); rb = b.substr(mid+1,b.length()); la = a.substr(1,lb.length()); ra = a.substr(a.length()-rb.length(),a.length()); t->left = new node(la[0]); genTree(t->left,la,lb); t->right = new node(ra[0]); genTree(t->right,ra,rb); } } void postOrder(node *t){ if(t!=NULL){ postOrder(t->left); postOrder(t->right); cout<<t->v; } } int main(int argc,char* argv[]){ while(cin>>A>>B){ node *root = new node(A[0]); genTree(root,A,B); postOrder(root); cout<<endl; } return 0; }