已知樹的先序和中序遍歷,求其後序遍歷問題

2021-09-20 06:45:41 字數 1542 閱讀 4997

初見安~超級激動地自己寫**解決了這麼個問題所以來發篇部落格。

問題就如標題所示了。【還是放一下具體題面

給出樹的前序遍歷及中序遍歷,求其後序遍歷。

存在多組資料,請做到檔案底結束

每組資料給出兩個字串,均不超過26個字母。分為前序、中序遍歷。

如題

dbacegf abcdefg

bcad cbad

acbfged

cdab

已知樹的先序和中序,首先是一定可以確定一棵樹的。至於如何處理,我們可以手動推一下試試。

再放乙個樣例——

abdegcf dbgeacf
dgebfca
首先我們第一反應——由先序遍歷(根左右)可得:樹的根節點為a。而中序遍歷(左根右)首為d,可得:樹的左半邊是由a出發一路遞迴到了點d。而後b在先序**現過,所以中序裡的db是在回溯;g沒有在先序出現過,所以是b的右子樹的內容了,e同理…………【剩下的自己去畫吧。

如果這樣找的話好像特判就特別多了。但是我們仔細觀察上邊的過程——我們一直在用中序找,以先序作為判定是根還是子樹的參考。既然如此何不再簡化先序的作用——用來找父親節點。什麼意思——後序遍歷(左右根)的遍歷方式其實類似於線段樹,先左後右最後回溯至其父親。如果我們找到了乙個父親節點,就相當於可以直接搜其兩個兒子節點,遇到葉子節點直接輸出即可。

可能你還是沒怎麼懂,我們用這個思路再找一遍吧——在上方的樣例2中,首先由abdegcf可知根節點為a。我們發現在中序中a的下標為(從0開始)4,所以中序中[ 0,  3 ]為最大左子樹,[ 5, 6 ]為最大的右子樹。我們分別遞迴——在左子樹dbge中,由先序可得b為根節點,所以d為左子樹,ge為右子樹。當然,再往下一層d也不過是單點,所以可以直接輸出了——最深最靠左的乙個結點。ge的話在先序中我們d已經用過了,所以再往後看——是e,所以g為e的孩子,但是e出現在了這個子樹的邊界處,所以遞迴下去的只有g,輸出,回溯,輸出根節點e,再回溯,輸出根節點b。這樣以a為根節點的左子樹就已經處理完了。右子樹同理。所以——我們用乙個遞迴就可以解決了。

下面就是**啦~

#includeusing namespace std;

string s1, s2;

int now;

bool vis[30];//s1

mapm;

void find(int l, int r)

int mid = s2.find(s1[now]);//start from 0

now++;

if(mid > l) find(l, mid - 1);//否則mid為邊界點,當做根節點處理,不必再遞迴

if(r > mid) find(mid + 1, r);

printf("%c", s2[mid]);//輸出這一子樹的根

}int main()

return 0;

}

迎評:)

——end——

二叉樹遍歷 已知前序遍歷和中序遍歷求其後序

1 九度上乙個關於二叉樹遍歷的問題。通過給定的前序遍歷與中序遍歷就可以確定二叉樹的結構。題目描述 輸入 兩個字串,其長度n均小於等於26。第一行為前序遍歷,第二行為中序遍歷。二叉樹中的結點名稱以大寫字母表示 a,b,c.最多26個結點。輸出 輸入樣例可能有多組,對於每組測試樣例,輸出一行,為後序遍歷...

樹 先序中序後序遍歷

題目分析 題目描述 description 求一棵二叉樹的前序遍歷,中序遍歷和後序遍歷 輸入描述 input description 第一行乙個整數n,表示這棵樹的節點個數。接下來n行每行2個整數l和r。第i行的兩個整數li和ri代表編號為i的節點的左兒子編號和右兒子編號。輸出描述 output d...

JZOF 已知前序遍歷和中序遍歷,求出其後序遍歷

題目 輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如 前序遍歷序列 1,2,4,7,3,5,6,8 和中序遍歷序列 4,7,2,1,5,3,8,6 列印出它的後序遍歷 public class binarytree public ...