信息學奧賽:1364:二叉樹遍歷(flist)
參考這篇客:https://blog.csdn.net/yanyanwenmeng/article/details/77833274
1364:二叉樹遍歷(flist)
時間限制: 1000 ms 內存限制: 65536 KB
提交數: 2306 通過數: 1495
【題目描述】
樹和二叉樹基本上都有先序、中序、後序、按層遍歷等遍歷順序,給定中序和其它一種遍歷的序列就可以確定一棵二叉樹的結構。
假定一棵二叉樹一個結點用一個字符描述,現在給出中序和按層遍歷的字符串,求該樹的先序遍歷字符串。
【輸入】
兩行,每行是由字母組成的字符串(一行的每個字符都是唯一的),分別表示二叉樹的中序遍歷和按層遍歷的序列。
【輸出】
一行,表示二叉樹的先序序列。
【輸入樣例】
DBEAC
ABCDE
【輸出樣例】
ABDEC
思路:
就拿題目的輸入樣例分析:
先看下二叉樹的中序遍歷圖解:圖的來源
二叉樹的層次遍歷就不用說了吧,先從根節點開始,一層一層的遍歷的。
我們在來看看這題要求什麼?題目要求的是先序遍歷吧,先序遍歷是這個樣子的:圖片來源。也是從根節點開始往下遍歷一根筋的先左後右。我來敘述下遍歷過程:先從根節點開始遍歷,根節點查詢完畢後一分爲二,可以看成是以B位根節點的樹和以C爲根節點的樹。然後從B節點開始遍歷,又可以看作是以D爲根節點的樹和以F爲根節點的…
好!下面給兩個字符串:
按中序遍歷結果:DBEAC // 假如叫s1串
按層次遍歷結果:ABCDE // 假如叫s2串
二叉樹先序的遍歷是從根節點開始的,所以就是要通過s1串和s2串找根節點。
先來找“第一個”根節點。我們知道層次遍歷一開始就是根節點,所以s2串的第一個字符一定就是第一個根節點。我們再來從中序找這個字符發現他在s1串下標爲3的地方,好按照中序的遍歷順序那麼s1串從下標爲0到下標爲3-1這部分(暫且叫s1[0:2])一定在根節點的左邊,s1串下標爲3+1到s1結束這部分(暫且叫s1[4:])一定是右串。
在從s1[0:2]中找根節點,怎麼找呢?還是從s2串中找,s1[0:2]串裏面最先在s2串中出現的哪個字符就是新的根節點。想想爲什麼?
下面附上代碼。
#include<iostream>
#include<string>
using namespace std;
string s1, s2;
void f(int start1, int end1, int start2, int end2){
int i, j, vis = 0;
for(i = start2; i <= end2; i++){ // 利用層次遍歷從中序中找“根”
for(j = start1; j <= end1; j++){
if(s1[j] == s2[i]){
cout<<s1[j];
vis = 1;
break;
}
}
if(vis) break;
}
if(j > start1) // 這個是限制邊界
f(start1, j - 1, start2, end2); // 查找左節點
if(j < end1)
f(j + 1, end1, start2, end2); // 查找右節點
}
int main(){
cin >> s1 >> s2;
f(0, s1.size() - 1, 0, s2.size() - 1);
return 0;
}
唉!敘述了這麼久感覺還是沒有說清楚。