二叉搜索树 二叉搜索树 (Binary Search Tree,简称 BST)是计算机科学中一种特定类型的容器,有时也被称为有序二叉树或排序二叉树。它们用于在内存中存储“项”(如数字、名称等),可以快速进行查找、添加和删除操作。它们可以用于实现动态集合或查找表,以便通过键来查找项(例如,通过姓名查找人的电话号码)。
二叉搜索树将其键按照排序顺序存储,以便查找和其他操作可以使用二分查找的原理:在树中查找键(或查找要插入新键的位置)时,从根到叶子遍历树,与树节点中存储的键进行比较,并根据比较结果决定是继续在左子树还是右子树中搜索。平均而言,这意味着每次比较都可以跳过树的约一半,因此每次查找、插入或删除操作的时间与树中存储的项数的对数成比例。这比在(未排序的)数组中按键查找项所需的线性时间要好得多,但比哈希表上的相应操作要慢。
下图是一个大小为 9、深度为 3 的二叉搜索树示例,根节点为 8。叶子节点未绘制。
BinarySearchTreeNode 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 export default class BinarySearchTreeNode extends BinaryTreeNode { constructor (value = null , compareFunction = undefined ) { super (value); this .compareFunction = compareFunction; this .nodeValueComparator = new Comparator (compareFunction); } insert (value ) { if (this .nodeValueComparator .equal (this .value , null )) { this .value = value; return this ; } if (this .nodeValueComparator .lessThan (value, this .value )) { if (this .left ) { return this .left .insert (value); } const newNode = new BinarySearchTreeNode (value, this .compareFunction ); this .setLeft (newNode); return newNode; } if (this .nodeValueComparator .greaterThan (value, this .value )) { if (this .right ) { return this .right .insert (value); } const newNode = new BinarySearchTreeNode (value, this .compareFunction ); this .setRight (newNode); return newNode; } return this ; } find (value ) { if (this .nodeValueComparator .equal (this .value , value)) { return this ; } if (this .nodeValueComparator .lessThan (value, this .value ) && this .left ) { return this .left .find (value); } if (this .nodeValueComparator .greaterThan (value, this .value ) && this .right ) { return this .right .find (value); } return null ; } contains (value ) { return !!this .find (value); } remove (value ) { const nodeToRemove = this .find (value); if (!nodeToRemove) { throw new Error ("Item not found in the tree" ); } const { parent } = nodeToRemove; if (!nodeToRemove.left && !nodeToRemove.right ) { if (parent) { parent.removeChild (nodeToRemove); } else { nodeToRemove.setValue (undefined ); } } else if (nodeToRemove.left && nodeToRemove.right ) { const nextBiggerNode = nodeToRemove.right .findMin (); if (!this .nodeComparator .equal (nextBiggerNode, nodeToRemove.right )) { this .remove (nextBiggerNode.value ); nodeToRemove.setValue (nextBiggerNode.value ); } else { nodeToRemove.setValue (nodeToRemove.right .value ); nodeToRemove.setRight (nodeToRemove.right .right ); } } else { const childNode = nodeToRemove.left || nodeToRemove.right ; if (parent) { parent.replaceChild (nodeToRemove, childNode); } else { BinaryTreeNode .copyNode (childNode, nodeToRemove); } } nodeToRemove.parent = null ; return true ; } findMin ( ) { if (!this .left ) { return this ; } return this .left .findMin (); } }
BinarySearchTree 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 export default class BinarySearchTree { constructor (nodeValueCompareFunction ) { this .root = new BinarySearchTreeNode (null , nodeValueCompareFunction); this .nodeComparator = this .root .nodeComparator ; } insert (value ) { return this .root .insert (value); } contains (value ) { return this .root .contains (value); } remove (value ) { return this .root .remove (value); } toString ( ) { return this .root .toString (); } }