二叉查找树
二叉查找树(BST), 又叫做二叉排序树,二叉搜索树,是一种对查找和排序都有用的特殊二叉树。
二叉查找树或者空树,或者满足下面三个性质:
1、若其左子树非空,则左子树上所有结点的值都小于根节点的值。
2、若其右子树非空,则右子树上所有结点的值都大于根节点的值。
3、其左右子树都是一棵二叉查找树。
二叉查找树的特性:左子树 < 根 < 右子树, 即二叉查找树的中序遍历是一个递增序列。
二叉查找树的查询
因为二叉查找树的中序遍历有序性,即得到的递增的序列,由于有序,查找与二分查找类似,每次都可以缩小查找范围,因此查找效率很高。
算法步骤:
1、若二叉查找树为空,则查找失败,返回空指针。
2、若二叉查找树非空,则将待查找关键字 key 与根结点的关键字 node.value 进行比较。
(1)如果 x=node.value, 则查找成功,返回查询到的当前结点 T。
(2)如果 x<node.value, 则递归查找左子树。
(3)如果 x>node.value, 则递归查找右子树。
算法分析:
时间复杂度: 最好的情况是 O(logn), 最坏情况是 O(n)。
代码实现:
/**
* 3、二叉查找树的查找
*/
findNodeByValue(root, value) {
//节点为空,则证明查找失败。
if (root == undefined || root == null) {
return null;
}
if (root.value == value) {
console.log(`root.value == value: ${
root.value} - ${
value}`);
return root;
}
if (root.value > value) {
console.log(`root.value > value: ${
root.value} - ${
value}`);
return this.findNodeByValue(root.leftNode, value);
}
if (root.value < value) {
console.log(`root.value < value: ${
root.value} - ${
value}`);
return this.findNodeByValue(root.rightNode, value);
}
}
二叉查找树的插入
因为二叉查找树的中序遍历存在有序性,所以首先要查找待插入元素的插入位置,当查找不成功时再将待插入元素作为新的叶子结点,成为最后一个查找节点的左孩子或者右孩子。
算法步骤:
1、若二叉查找树为空,则创建一个新的节点S,将待插入关键字放入新节点的数据域,然后将 S 结点作为根结点,S节点的左右子树都设置为空。
2、若二叉查找树非空,则将带插入元素 e 和根结点的关键字 node.value 比较。
(1) 如果 e <= node.value, 则将 e 插入到左子树中。
(2) 如果 e > node.value, 则将 e 插入到右子树中。
算法分析:
在二叉查找树中进行插入操作时需要先查找插入位置,插入本身只需要常数时间,但是查找插入位置的时间复杂度为O(logn)
代码实现:
/**
* 2、二叉查找树的插入
*/
insert(root, value) {
//树为空的情形
if (root == null || root == undefined) {
root = new TreeNode(value, null, null);
return root;
}
//如果 `插入的值` 比当前节点小,则继续查找当前节点的左子树。
if (root.value >= value && root.leftNode) {
this.insert(root.leftNode, value);
} else if (root.value >= value) {
//左子树已经不存在,则成为其左节点。
root.leftNode = new TreeNode(value, null, null);
}
//如果 `插入的值` 比当前节点大,则继续查找当前节点的右子树。
if (root.value < value && root.rightNode)