樹、基礎資料結構

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

  1. 直接將元素push_back至尾端
  2. 向上比較元素,不斷的上推
  3. 上方元素已經比目前元素大,則停止

heap popping

  1. 將根節點元素替換為末端的元素
  2. 向下比較左右子節點目前的元素
  3. 若下方的最大,則往該方向交換
  4. 若目前元素最大或已沒有下方的節點,則停止

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