二叉樹遍歷有先序、中序和後序三種遍歷方式。
先序:根左右
中序:左根右
後序:左右根
給出樹的根節點後可根據遞迴求得不同的序列,這方面不是這的重點先按下不表。
這裡的重點在於如何在知道了二叉樹的2種遍歷序列的基礎上求得第3種遍歷序列。這裡有兩種方法,一種是採用線段數的做法,第二種是採用建樹的做法。
先來講講線段樹的方法:
線段樹就是採用陣列來儲存一棵樹的節點編號,父子節點的數學關係如下
接下來,以「已知後序和中序序列求先序序列」為例講講如何知二求一!
下面我們給出乙個後序遍歷序列和乙個中序遍歷序列:
後序:2 3 1 5 7 6 4
中序:1 2 3 4 5 6 7
由二叉樹遍歷的性質我們知道後序遍歷最後乙個輸出的根節點④,而根據中序遍歷的性質我們也能知道根節點的兩側分別為左子樹①②③和右子樹⑤⑥⑦,後序遍歷先看根節點的左子樹那麼我們根據其遍歷的性質又可知道左子樹的根節點①,再看中序序列發現①沒有左子樹只有右子樹,因此根據後序序列它的右子樹根為③且它只有左子樹②。之後我們再來看④的右子樹,根據後序遍歷的性質有其右子樹的根⑥,根據中序遍歷知道了⑥的左右子樹分別為⑤⑦。過程如下圖:
下面說下**的實現(不建樹的方法):
演算法個關鍵就在於根據後序序列求出根節點然後在中序序列中找出根節點隨之劃分出左右子樹,層層遞迴。
1我們再來講一下通過用建樹的方法來求二叉樹,這種方法比較複雜一般用於節點數太多的情況,二叉樹是以鍊錶的形式儲存的。//已知二叉樹中序、後序,求先序。
2 #include3
using
namespace
std;45
int mid[7] = ;
6int post[7] = ;78
//root為根在後序遍歷序列裡的位置,start和end是子樹的其實位置在中序遍歷序列裡的位置
9void pre_order(int root,int start,int
end)
13int
i;14 i =start;
15//
中序序列中尋找根節點
16while(ipost[root])
19 printf("
%d "
,post[root]) ;
20//
左子樹根的位置(後序序列):當前根節點-右子樹節點數-1
21 pre_order(root-(end-i)-1,start,i-1
); 22
//右子樹根的位置(後序序列):當前根節點-1
23 pre_order(root-1,i+1
,end);24}
2526
intmain()
我們一般先用寫乙個節點型別的結構體
struct之後是遞迴函式建樹的過程:tree;
tree* order(int root,int begin,intend)
inti;
i =begin;
tree *pn;
pn = new
tree();
while(ipri[root])
pn->r =pri[root];
pn->leftcid = order(root+1,begin,i-1
); pn->rightcid = order(root+(i-begin)+1,i+1
,end);
return
pn;}
int注意這裡函式返回的是指標,因為結構體中左右孩子都是指標型別,為了統一型別初始設根節點最好也要為指標型別。main()
for(int i=0;i)
node = order(0,0,n-1
);}
還有就是在c++裡動態開闢記憶體要寫為:
tree *pn;意思就是,先建立乙個指標型別的變數,再向記憶體申請空間,切記一行都不能少!!(第一次寫這個**在這裡除錯了很久t_t)pn = new tree();
最後說一下,用建樹的方法建完二叉樹後可用dfs完成三種遍歷,用bfs完成按層輸出。
求二叉樹的層次遍歷
time limit 1000ms memory limit 65536kb problem description 已知一顆二叉樹的前序遍歷和中序遍歷,求二叉樹的層次遍歷。input 輸入資料有多組,輸入t,代表有t組測試資料。每組資料有兩個長度小於50的字串,第乙個字串為前序遍歷,第二個為中序遍...
求二叉樹的層次遍歷
time limit 1000ms memory limit 65536kb problem description 已知一顆二叉樹的前序遍歷和中序遍歷,求二叉樹的層次遍歷。input 輸入資料有多組,輸入t,代表有t組測試資料。每組資料有兩個長度小於50的字串,第乙個字串為前序遍歷,第二個為中序遍...
求二叉樹的層次遍歷
time limit 1000 ms memory limit 65536 kib submit statistic problem description 已知一顆二叉樹的前序遍歷和中序遍歷,求二叉樹的層次遍歷。input 輸入資料有多組,輸入t,代表有t組測試資料。每組資料有兩個長度小於50的字...