- 題目描述:
-
二叉樹的前序、中序、后序遍歷的定義:
前序遍歷:對任一子樹,先訪問跟,然后遍歷其左子樹,最后遍歷其右子樹;
中序遍歷:對任一子樹,先遍歷其左子樹,然后訪問根,最后遍歷其右子樹;
后序遍歷:對任一子樹,先遍歷其左子樹,然后遍歷其右子樹,最后訪問根。
給定一棵二叉樹的前序遍歷和中序遍歷,求其后序遍歷(提示:給定前序遍歷與中序遍歷能夠唯一確定后序遍歷)。
- 輸入:
-
兩個字符串,其長度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;
}
