# 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