二叉搜索树(BST)是一种二叉树,其中每个节点遵循以下属性:
- 节点的左子树只包含小于当前节点的值的节点。
- 节点的右子树只包含大于当前节点的值的节点。
- 左右子树本身也是二叉搜索树。
以下是一个二叉搜索树的实现及详细注释:
定义二叉搜索树节点:
class TreeNode {
constructor(value) {
this.value = value; // 节点的值
this.left = null; // 左子节点
this.right = null; // 右子节点
}
}
二叉搜索树的定义与操作:
class BinarySearchTree {
constructor() {
this.root = null; // 树的根节点
}
// 插入节点
insert(value) {
const newNode = new TreeNode(value);
if (!this.root) {
this.root = newNode;
} else {
this._insertNode(this.root, newNode);
}
}
_insertNode(node, newNode) {
if (newNode.value < node.value) {
if (!node.left) {
node.left = newNode;
} else {
this._insertNode(node.left, newNode);
}
} else if (newNode.value > node.value) {
if (!node.right) {
node.right = newNode;
} else {
this._insertNode(node.right, newNode);
}
} // 如果新节点的值等于当前节点值,我们不插入,保持唯一值。
}
// 查找节点
search(value) {
return this._searchNode(this.root, value);
}
_searchNode(node, value) {
if (!node) return false;
if (value < node.value) {
return this._searchNode(node.left, value);
} else if (value > node.value) {
return this._searchNode(node.right, value);
} else {
return true; // 找到节点
}
}
// 中序遍历
inOrder(callback) {
this._inOrder(this.root, callback);
}
_inOrder(node, callback) {
if (node) {
this._inOrder(node.left, callback);
callback(node.value);
this._inOrder(node.right, callback);
}
}
// 删除节点
remove(value) {
this.root = this._removeNode(this.root, value);
}
_removeNode(node, value) {
if (!node) return null;
if (value < node.value) {
node.left = this._removeNode(node.left, value);
return node;
} else if (value > node.value) {
node.right = this._removeNode(node.right, value);
return node;
} else { // 当前节点就是要删除的节点
// 无子节点
if (!node.left && !node.right) {
return null;
}
// 只有一个子节点
if (!node.left) {
return node.right;
} else if (!node.right) {
return node.left;
}
// 有两个子节点
const aux = this._findMinNode(node.right);
node.value = aux.value;
node.right = this._removeNode(node.right, aux.value);
return node;
}
}
_findMinNode(node) {
while (node && node.left) {
node = node.left;
}
return node;
}
}
使用示例:
const bst = new BinarySearchTree();
bst.insert(15);
bst.insert(10);
bst.insert(25);
bst.insert(7);
bst.insert(13);
bst.insert(20);
bst.insert(27);
console.log(bst.search(13)); // true
console.log(bst.search(100)); // false
bst.inOrder(value => console.log(value));
// 输出:7, 10, 13, 15, 20, 25, 27
bst.remove(15);
bst.inOrder(value => console.log(value));
// 输出:7, 10, 13, 20, 25, 27