持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天,点击查看活动详情
二分搜索树
-
二分搜索树也是二叉树
-
二分搜索树的每个节点的值:
- 大于其左子树的所有节点的值
- 小于其右子树的所有节点的值
- 存储的元素具有可比较性
在二分搜索树中查询元素
力扣700题
- 通过递归的方式查询还是比较简单的。
- 如果根节点的值大于val就在其左子树中查找,否则就在右子树中查找。
- 如果递归找不到值,root变为空的话就返回null 查询失败,无对应值
- 找到 root.val === val的值时就返回对应的节点
二分搜索树的遍历
先序遍历:
// 先序遍历(根左右)
preorderTraversal() {
const result = [];
this.preorderTraversalNode(this.root, result);
return result;
}
preorderTraversalNode(node, result) {
if (node === null) return result;
result.push(node.key); //先存储根元素,然后左子树,右子树
this.preorderTraversalNode(node.left, result);
this.preorderTraversalNode(node.right, result);
}
中序遍历和后序遍历也是类似
相关算法
二叉搜索树的最小绝对差
当我们看到在二叉搜索树中比较什么差值时,就把它想成在一个有序数组上求最值,求差值,
因为二叉搜索树的遍历是有序的,在有序的数组中求差值什么的最简单
对比一个有序数组[1,2,3,5,6,8]
差值最大的时候坑定是 末尾的元素 - 开头的元素
同样,最小差值的肯定是两个相邻的元素
就可以很容易求得了
二叉树的公共祖先
这道题要求求得两个节点最近的公共祖先。
公共祖先满足什么条件
就是说,这两个节点,往上走时最先同时经过的地方。(看一下例子就能理解了)
说明这个 公共祖先的节点 下面的子节点肯定有 p和q。那么这个p和q 即可能都在左子树,可能都在右子树,可能分布在两边。
那么我们就从下到上的来遍历出这个树。肯定是使用后序遍历的方法。
递归找到每个叶子节点,然后从下往上寻找符合条件的 节点。
如果找到的话,对应的 p q节点,就向上返回这个节点,如果找不到就向上返回 null
然后在每个节点进行判断,看这个节点的左子树和右子树是否检查到 p q ,检查(都检查到或者检查到一个)到就标明root返回。
检查到左子树或右子树上不为null 就返回相应的 值
如果都找到了,那这个节点就是要找的公共祖先,并一直返回到最上面。
二叉搜索树的公共祖先
就像上面那道题一样,
但二分搜索树的节点是有特点的
我们可以很轻易的发现 从上往下遍历,找到的第一个 p.val < node.val < q.val的node时,这个节点就是索要找的值,所以就可以更方便的解决这道题,不需要把整个树全部遍历,只需要遍历复合范围条件的子树就可以