一、二叉樹的定義
二叉樹(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 }