題目描述
二叉樹是每個內部結點最多只有兩個子結點且兩個子結點有序的樹。如下圖就是一棵二叉樹:
對於一棵二叉樹,有三種基本遍歷方式:
1.前序遍歷:先訪問根結點,然后再前序遍歷左子樹,最后前序遍歷右子樹;
2.中序遍歷:先中序遍歷左子樹,然后訪問根結點,最后中序遍歷右子樹;
3.后序遍歷:先后序遍歷左子樹,然后后序遍歷右子樹,最后訪問根結點。
對於上圖,前序遍歷的結果是ABDEHCFGI。中序遍歷的結果是DBEHAFCIG,后序遍歷的結果是DHEBFIGCA。
現在給出二叉樹的前序和中序遍歷,請輸出相應的后序遍歷。
輸入
第一行前序遍歷的結果
第二行中序遍歷的結果
都是大寫字母,且結點的標識不重復,最多只有100個結點。
輸出
輸出后序遍歷的結果
樣例輸入
ABDEHCFGI
DBEHAFCIG
樣例輸出
DHEBFIGCA
Source Code
#include <iostream>
#include <string.h>
using namespace std;
char a[110],b[110];//a[]是前序遍歷的結果 b[]是中序遍歷的結果
void dfs(int f1,int e1,int f2,int e2)
{
if(f1>e1) return;//如果找不到子節點就退出(起點大於終點)
int rt=f1;//rt是根節點
int p = 0;
//計算出左子樹或者右子樹的下一層根節點
for(int i=f2;i<=e2;i++)
if(b[i]==a[rt])//如果找到了頂點
{
p=i;//p代表頂點在b[]里面的位置 即b[p]
break;
}
int ls=p-1-f2+1;//ls表示長度
//int rs=e2-(p+1)+1;
dfs(f1+1,f1+1+ls-1,f2,p-1);//遞歸處理左子樹
//f1+1:a[]的左子樹的起點 f1+1+ls-1:a[]的左子樹的終點
//f2:b[]的左子樹的起點 p-1:b[]的左子樹的終點
dfs(f1+1+ls-1+1,e1,p+1,e2);//遞歸處理右子樹
//f1+1+ls-1+1:a[]的右子樹的起點 e1:a[]的右子樹的終點
//p+1:b[]的右子樹的起點 e2:b[]的右子樹的終點
printf("%c",a[rt]);//如果這是一個葉節點(既沒有左子樹,也沒有右子樹),就輸出它
}
int main()
{
//scanf("%s%s",a,b);
cin >> a >> b;
dfs(0,int(strlen(a))-1,0,int(strlen(b))-1);//起點
cout << endl;
return 0;
}
/*
思路總結:
先以a為頂點,遞歸尋找a的左子樹 如果a有左子樹,先判斷下一個節點b是否為頂點 (判斷b是否為頂點:判斷b是否有左右子樹)
找到b的左子樹的下一個節點d 再繼續判斷d是否有左右子樹 如果沒有,d為葉節點
在找到b的右子樹的下一個節點e 判斷e的左右子樹 如果有,繼續判斷下一個節點h是否有左右子樹 直到找到h葉子節點
在找到a的右子樹的下一個節點c 判斷c的左右子樹 如果有,繼續判斷下一個節點 f和g 是否有左右子樹 直到找到i葉子節點
每次找到葉子節點就輸出
*/