---
# System prepended metadata

title: BST 二元搜尋樹
tags: [資料結構, 排序法]

---

# BST 二元搜尋樹
###### tags: `資料結構` `排序法`
### 定義
* 可以是空的
* 每一個節點含有uniqlo key
* 左子樹的節點小於父節點
* 右子樹的節點大於父節點


---
### Search 
1. 從 root 開始，先與 root 比較
2. 若比 root **小**就搜尋**左子樹**
3. 若比 root **大**就搜尋**右子樹**
4. **遞迴**直到找到或者已經沒有子樹可以尋找
```
public Node search(Node root, int key) 
{ 
    //若root是空的或root的值==key 
    if (root==null || root.key==key){
        return root;
    }
    
    //key大於root.key
    if (root.key < key){
        return search(root.right, key); 
    }
    
    //key小於root.key
    return search(root.left, key); 
} 
```


---
### Insert 
1. 依大小插入節點在適當的位置
2. 從 root 尋訪
3. 同 search，比 root **小**就往**左子樹**找
4. 比 root **大**就往**右子樹**找
5. 遞迴做法：`root.left = insertRec(root.left, key);`
6. 若此時是一個**空節點**，就建立要插入的節點並**回傳節點(對應第五點)**

```
Node insertRec(Node root, int key){ 
    if (root == null){ 
        root = new Node(key); 
        return root; 
    } 
  
    if (key < root.key) 
        root.left = insertRec(root.left, key); 
    else if (key > root.key) 
        root.right = insertRec(root.right, key); 
  
    return root; 
} 
```


---
### Detele 
1. 若比 root.key **小**，遞迴刪除 **root.left** 並回傳
2. 若比 root.key **大**，遞迴刪除 **root.right** 並回傳
3. 若要刪除的是root
    1. 若沒有兒子節點直接刪除並回傳null
    2. 若只有一個兒子樹直接回傳兒子節點 (為新的root)
    3. 若有兩個兒子樹
        * 找**左子樹**的最**大**值 或
        * 找**右子樹**的最**小**值 以下程式取此選項
        * 設 `root.key = minValue(root.right)`
        * 將該最**小**值的節點刪除並回傳**新的 root.right**
        * `root.right = deleteRec(root.right, root.key);`

```
Node deleteRec(Node root, int key)
    {
        if (root == null)
            return root;
 
        if (key < root.key)
            root.left = deleteRec(root.left, key);
        else if (key > root.key)
            root.right = deleteRec(root.right, key);
        else {
            
            if (root.left == null)
                return root.right;
            else if (root.right == null)
                return root.left;
            
            root.key = minValue(root.right);    //把新的值放入
            root.right = deleteRec(root.right, root.key);  
            //刪掉已成為新的root的值，存回root.right
        }
        return root;
    }
```

---
### 複雜度
**搜尋 & 插入**時間複雜度 
average = O(logn)，若是平衡BST
worst case = O(n)，chain BST (skewed)



---
## Tree Sort
### 概念
以 **BST** 來實作排序，再用 **inorder** 方式尋訪即可得到排序好的結果

### 步驟
1. 用**插入**方式來建立BST
2. **inorder** traversal

### 複雜度
* best case = average case = **O(nlogn)**
* worst case = **O(n*n)(左傾數、右傾數)**

---
參考資料：**GeeksforGeeks** website and **WilliamFiset** youtube channel