-TREE-
by h94usu/6
CONTENTS
- Introduction 介紹
- definitions 定義
- terms 術語
- properties 性質
- Set up a tree 建立
- Binary tree 二元樹
- Traversal 遍歷
Introduction
"樹"的基本介紹
definition 定義
-
任兩點之間都相通,沒環的連通圖
- 「環」: 能繞圈
- 「連通」: 任兩點皆有路線使相連
環
連通
樹
v
v
x
x
v
v
x
v
v
x
x
x
terms 術語
a
b
c
d
e
f
g
根節點 root
節點 node
葉節點 leaf node
邊 edge
terms 術語
a
b
c
d
e
f
g
d, c 為b 的子節點 child
b, c 為兄弟節點 siblings
a 為 b, c 的父節點 parent
a, b 為d 的祖先 ancestor
d, e, g 為b 的子代 descendant
☐ 為b 的子樹 subtree
分4 層level, 深度depth 為4
level 0
level 1
level 2
level 3
properties 性質
- 任何節點皆可當根節點
- 任兩點恰有一條無重複點的路徑
- 一棵n 個節點的樹恰有(n-1) 條邊
a
b
c
d
e
b
d
a
e
c
5 個節點
4 條邊
Set Up a Tree
建立一棵"樹"
linked list (不好的方法)
0
Advanced issue found▲
-
建一個名Node 的structure
- 存節點的值
- 存Node型態指標
#inlcude <iostream>
using namespace std;
struct Node{
int _data; //不一定是int
Node *_child1, *_child2, *_child3... ;
};
△注意: 不確定有幾個子節點,開太大會造成記憶體的浪費
linked list (好方法)
-
建一個名Node 的structure
- 存節點的值
- 用vector 紀錄其子節點
#inlcude <iostream>
#include <vector>
using namespace std;
struct Node{
int _data; //不一定是int
vector<Node*> _child;
};
dynamic array (最常用)
-
建兩個陣列
- 建一個陣列存每個節點的數值
- 開一個vector 陣列存每個編號的子節點
#inlcude <iostream>
#include <vector>
using namespace std;
int data[size];
vector<int> child[size];
//size 即為節點個數
Binary Tree
二元樹
definition 定義
- 一個沒環的連通圖
- 每個節點定義有唯一的父節點且不大於2個子節點
#inlcude <iostream>
using namespace std;
struct Node{
int _data;
Node *left_child, *right_child;
};
properties 性質
- 第i 層最最多有2^i 個節點
- 深度為k 的二元樹最多有2^(k+1)-1 個節點
- 葉節點數 = 分支度為2 的節點數 + 1
- 二元樹的節點有左、右次序之分
-
第n 個節點
- child 為編號2n, 2n+1
- patent 為 n/ 2
△注意: 定義根節點所在深度為第0 層
a
b
c
d
e
f
Types 二元樹的種類
0
Advanced issue found▲
- 滿二元樹 full binary tree
- 完全二元樹 complete binary tree
- perfect binary tree
a
b
c
d
e
f
a
b
c
d
e
f
d
full binary tree
complete binary tree
Full Binary Tree 滿二元樹
0
Advanced issue found▲
- 每一層上的節點數都是最大節點數(2個)
-
一棵深度為k 的滿二元樹
- 第i 層有2^i 個節點
- 有2^k - 1個節點
- 有2^(k-1) 個葉節點
- 節點各樹必為奇數
a
b
c
d
e
f
d
full binary tree
Complete Binary Tree 完全二元樹
0
Advanced issue found▲
- 除最後一層每層節點數都是最大節點數(2個)
- 最後一層不是滿的就是右邊缺一節點
- 深度為k 的完全二元樹
-
有2^(k-1) 個葉節點
- 至少有2^(k-1) 個節點
- 至多有2^k - 1個節點
a
b
c
d
e
f
complete binary tree
Tree Traversal
"樹"的遍歷
Types 遍歷的種類
0
Advanced issue found▲
-
深度優先遍歷 Depth-first search (DFS)
- 前序遍歷 Pre-Order
- 中序遍歷 In-Order
- 後序遍歷 Post-Order
-
廣度優先遍歷 Breadth-first search (BFS)
- 層序遍歷 Level-order
Pre-Order 前序遍歷
0
Advanced issue found▲
- 先存取根,再存取子樹
void pre_order_traversal(Node *root) {
cout << root->data << " ";
if (root->left_child != NULL) //如有子代則讀取其子樹
pre_order_traversal(root->left_child);
if (root->right_child != NULL) //另一側
pre_order_traversal(root->right_child);
}
a
b
c
d
e
output: a b d e c
根
△根在最前
In-Order 中序遍歷
0
Advanced issue found▲
- 先存取左子樹,再存取根,最後存取右子樹
void in_order_traversal(Node *root) {
if (root->left_child != NULL) //如有子代則讀取其子樹
in_order_traversal(root->left_child);
cout << root->data << " ";
if (root->right_child != NULL) //另一側
in_order_traversal(root->right_child);
}
a
b
c
d
e
output: d b e a c
根
△根在中間
Post-Order 後序遍歷
0
Advanced issue found▲
- 先存取子樹,再存取根
void post_order_traversal(Node *root) {
if (root->left_child != NULL) //如有子代則讀取其子樹
post_order_traversal(root->left_child);
if (root->right_child != NULL) //另一側
post_order_traversal(root->right_child);
cout << root->data << " ";
}
a
b
c
d
e
output: d e b c a
根
△根在最後
Level-Order 層序遍歷
0
Advanced issue found▲
- 先存取離根節點最近的節點
void level_order_traversal(node *root) {
int head = 0, tail = 0;
node *p[SIZE] = {NULL};
node *tmp;
if (root != NULL) {
p[head] = root;
tail++;
cout << p[head]->data << " ";
}
else return;
while (head < tail) {
tmp = p[head];
cout << root->data << " ";
if (tmp->left_child != NULL) { //如有子代則讀取其子樹
p[tail] = tmp->left_child;
tail++;
}
if (tmp->right_child != NULL) { //另一側
p[tail] = tmp->right_child;
tail++;
}
head++;
}
return;
}
a
b
c
d
e
output: a b c d e
0
Advanced issue found▲
根
△根在最前
Tree
By h94usu6
Tree
自助學習成發
- 144