樹、基礎資料結構
Tree
樹
- 樹是多數資料結構的基礎
- 樹有很多圖論的性質
- 同時做為資料結構也有許多好性質
Binary Tree
Binary Tree
差不多長這樣
B-Tree in Practice
- 利用指標(偽指標?)!
- 動態開點!
B-Tree by Array
- Binary Tree也可以用陣列寫!
Tree Traversal
- 把樹上所有點走過(遍歷)
- 通常會用遞迴處理
- 前序
- 中序
- 後序
前/中/後序遍歷
- 遞迴時的順序
- 前序是先處理目前的點再遞迴
- 中敘是遞迴左邊,處理目前的點,遞迴右邊
- 後續是先遞迴再處理目前的點
Code
void dfs(int cur){
cout << cur << '\n'; //前序的訪問時間點
dfs(left);
cout << cur << '\n'; //中序的訪問時間點
dfs(right);
cout << cur << '\n'; //後序的訪問時機點
}
- 類似B-Tree的結構?
BST
Binary Search Tree
- 每個節點至多存在兩個子節點
- 左子節點的值小於父節點
- 右子節點的值大於父節點
Self Balance BST
- Treap
- 紅黑樹
- 交給STL幫你實作!
實作一般的BST
- 利用物件導向!
建構節點
- 節點需要儲存什麼資訊?
- 子節點
- Key Value
- 資料
建構節點
struct node{
int key;
int data;
node *left, *right;
};
建構節點(建構子)
struct node{
int key;
int data;
node *left, *right;
node(int key):key(key){
left = nullptr;
right = nullptr;
}
};
尋找節點
struct node{
int find_key(int key_to_find){
if (key_to_find == key) return data;
else if (key_to_find < key){
if (left != nullptr) return left->find_key(key_to_find);
else return -1;
}
else{
if (right != nullptr) return right->find_key(key_to_find);
else return -1;
}
}
};
Perfect Binary Tree
Perfect Binary Tree
- 完美二元樹擁有洽 \(2^{dep} - 1\) 個節點
Storing Perfect B-Tree
- 可以用陣列儲存
- 1-base時
- 左子節點 \(2x\)
- 右子節點 \(2x+1\)
- 父節點為 \( \lfloor \frac{x}{2} \rfloor \)
- 0-base時
- 左子節點 \(2x+1\)
- 右子節點 \(2x+2\)
- 父節點為 \( \lfloor \frac{x-1}{2} \rfloor \)
Heap
Near Perfect
- 還記得完美二元樹嗎
- Heap 是近乎完美的二元樹
- 只有最底層沒有滿
- 而且最底層的元素都靠左
Properties of Heap
- 假設為max-heap
- 每個父節點都大於子節點
- 根節點必為最大值
- min-heap則相反
max-heap
Storing Heap
- heap是近乎完美的二元樹
- \(\Rightarrow\) 可以套用某些完美二元樹的性質!
- 用陣列儲存!
heap insertion
- 直接將元素push_back至尾端
- 向上比較元素,不斷的上推
- 上方元素已經比目前元素大,則停止
heap popping
- 將根節點元素替換為末端的元素
- 向下比較左右子節點目前的元素
- 若下方的最大,則往該方向交換
- 若目前元素最大或已沒有下方的節點,則停止
Complexity
- 操作數量最多都是深度
- 完美二元樹的深度為 \(O(\log node)\)
- 有 \(n\) 個點的 heap push/pop 複雜度為 \(O(\log n)\)
Code
struct min_heap{
vector <int> v;
void push(int x){
int i = v.size();
v.pb(x);
while (i > 1){
//do something
i /= 2;
}
}
void pop(){
swap(v[1], v.back());
v.pop_back();
int i = 1;
while (true){
int next_node = i;
//compare 3 nodes(if exists)
//find the min node
if (i == next_node) break;
swap(v[i], v[next_node]);
i = next_node;
}
}
};
線段樹
0 | 1 | 2 | 3 | 4 | 5 |
\(w_1 = 2, w_2 = 3, w_3 = 2, w_4 = 1, w_5 = 5\)
樹與基礎資料結構
By yungyao
樹與基礎資料結構
- 132