二叉樹的三種遍歷方式


一、二叉樹的定義

二叉樹(Binary Tree)的遞歸定義:二叉樹要么為空,要么由根節點(root)、左子樹(left subtree)和右子樹(right subtree)組成,而左子書和右子樹分別是一顆二叉樹。注意,在計算機中,樹一般是"倒置"的,即根在上,葉子在下。

二、二叉樹的層次遍歷

三種遍歷方式:先序遍歷、中序遍歷、后序遍歷(根據根節點的順序)

PreOrder(T) = T的根節點 + PreOrder(T的左子樹) + PreOrder(T的右子樹)

InOrder(T) = InOrder(T的左子樹) + T的根節點 + InOrder(T的右子樹)

PostOrder(T) = PostOrder(左子樹) + PostOrder(右子樹)

其中加號表示字符串連接

這三種遍歷都是遞歸遍歷或者說深度優先遍歷 (DFS,Depth-First-Search)

三、已知兩種遍歷方式,推出另一種遍歷方式

先序+中序---->后序

后序+中序---->先序

因為后序或先序可以直接得到根節點,然后只要在中序遍歷中找到,就知道左右子樹的中序和后序遍歷,遞歸下去就可以構造出二叉樹了。

四、樣例

(1) 題意:給一顆點帶權(各權值都不相同,都是小於10000的整數)的二叉樹的中序和后序遍歷,找一個葉子節點使它到根的路徑上的權應盡量少。

(2) 代碼實現:

 1 #include<stdio.h>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<string>
 6 #include<sstream>
 7 using namespace std;
 8 
 9 const int INF = 0x3f3f3f3f;
10 //因為各節點的權值各不相同且都只是整數,直接用權值作為節點編號
11 const int maxn = 10000 + 10;    
12 int in_order[maxn], post_order[maxn], lch[maxn], rch[maxn];
13 int n;
14 int best, best_sum;
15 
16 //按行讀取數據,並存到數組中
17 bool read_list(int *a)
18 {
19     string line;
20     if (!getline(cin, line))  return false;
21     stringstream ss(line);
22     n = 0;
23     int x;
24     while (ss >> x)  a[n++] = x;
25     return n > 0;
26 }
27 
28 //把in_order[L1,R1]和post_order[L2,R2]建成一棵二叉樹,返回樹根
29 int build(int L1, int R1, int L2, int R2)
30 {
31     if (L2 > R2)  return 0;  //空樹
32     int root = post_order[R2];
33     int pos = L1;
34     while (in_order[pos] != root)  pos++;
35     int cnt = pos - L1;
36     lch[root] = build(L1, pos - 1, L2, L2 + cnt - 1);
37     rch[root] = build(pos + 1, R1, L2 + cnt, R2 - 1);
38     return root;
39 }
40 
41 //從根節點出發,中序遍歷,查找最小值
42 void dfs(int u, int sum)
43 {
44     sum += u;
45 
46     //到達葉子節點,循環終止
47     if (!lch[u] && !rch[u])
48     {
49         if (sum < best_sum)
50         {
51             best = u;
52             best_sum = sum;
53         }
54         return;
55     }
56 
57     //加了個剪枝:如果當前的和大於當前的最小和,就不必從這條路繼續搜
58     if (lch[u] && sum < best_sum)  dfs(lch[u], sum);
59     if (rch[u] && sum < best_sum)  dfs(rch[u], sum);
60 }
61 
62 int main()
63 {
64     while (read_list(in_order))
65     {
66         read_list(post_order);
67         build(0, n - 1, 0, n - 1);
68 
69         best_sum = INF;
70         dfs(post_order[n - 1], 0);
71         cout << best << endl;
72     }
73     return 0;
74 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM