二叉查找樹(英語:Binary Search Tree),也稱爲二叉查找樹、有序二叉樹(ordered binary tree)或排序二叉樹(sorted binary tree)
他擁有如下性質:node
圖中的二叉樹就是一顆二叉查找樹git
const nodes = { value: 6, left: { value: 3, left: { value: 1, left: { value: 0 }, right: { value: 2 } }, right: { value: 5 } }, right: { value: 8, left: { value: 7 }, right: { value: 9 } } }
在二叉查找樹b中查找x的過程爲:github
const SearchBST = (tree, value) => { if (!tree) { return false } if (value === tree.value) { return tree } if (value < tree.value) { return SearchBST(tree.left, value) } return SearchBST(tree.right, value) }
向一個二叉查找樹b中插入一個節點s的算法,過程爲:算法
const InsertBST = (tree, value, parent, key) => { if (!tree) { parent[key] = { value } return true } if (tree.value === value) { return false } if (tree.value > value) { return InsertBST(tree.left, value, tree, 'left') } return InsertBST(tree.right, value, tree, 'right') }
相比較其餘算法, JS 的實現感受有些不足數據庫
二叉搜索樹的節點刪除包括兩個過程,查找和刪除。segmentfault
在二叉查找樹刪去一個結點,分三種狀況討論:數組
節點度能夠當作分支數數據結構
const DeleteBST = (root, value) => { if (!root) { return false } if (root.value === value) { return DELETE(root) } if (root.value > value) { return DeleteBST(root.left, value, root, 'left') } return DeleteBST(root.right, value, root, 'left') } const DELETE = (root, parent, key) => { // 在這裏實現三種狀況 // 狀況 1 沒有左右子節點 可直接刪除 if (!root.left && !root.right) { parent[key] = null return true } // 狀況 2 只有一個子節點 從新鏈接便可 if (!root.right) { const q = root.left root.value = q.value root.left = q.left root.right = q.right return true } if (!root.left) { const p = root.right root.value = p.value root.left = p.left root.right = p.right return true } // 狀況 3 // 刪除節點後,爲了維持二叉搜索樹的結構特性,須要從其左子樹中選出一個最大值的節點,「上移」到刪除的節點位置上 let temp = root let l = root.left while (l.right) { temp = l l = l.right } root.value = l.value if (root != temp) { temp.right = l.left } else { temp.left = l.left } return true }
雖然二叉查找樹的最壞效率是O(n),但它支持動態查詢,且有不少改進版的二叉查找樹可使樹高爲O(log n),從而將最壞效率降至O(log n),如AVL樹、紅黑樹等。spa
二叉查找樹它既有鏈表的快速插入與刪除操做的特色,又有數組快速查找的優點,應用十分普遍,例如在文件系統和數據庫系統通常會採用這種數據結構進行高效率的排序與檢索操做code
倉庫地址: https://github.com/Grewer/notes
參考: