二分搜索树学习笔记

105 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天,点击查看活动详情

二分搜索树

  • 二分搜索树也是二叉树

  • 二分搜索树的每个节点的值:

    • 大于其左子树的所有节点的值
    • 小于其右子树的所有节点的值

image-20221002182759632

image-20221002183006033

  • 存储的元素具有可比较性

在二分搜索树中查询元素

力扣700题

image-20221007092313800

  • 通过递归的方式查询还是比较简单的。
  • 如果根节点的值大于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);
}

中序遍历和后序遍历也是类似

相关算法

二叉搜索树的最小绝对差

image-20221007145440673

当我们看到在二叉搜索树中比较什么差值时,就把它想成在一个有序数组上求最值,求差值,

因为二叉搜索树的遍历是有序的,在有序的数组中求差值什么的最简单

image-20221007145650208

对比一个有序数组[1,2,3,5,6,8]

差值最大的时候坑定是 末尾的元素 - 开头的元素

同样,最小差值的肯定是两个相邻的元素

就可以很容易求得了

二叉树的公共祖先

image-20221007165723970

这道题要求求得两个节点最近的公共祖先。

公共祖先满足什么条件

就是说,这两个节点,往上走时最先同时经过的地方。(看一下例子就能理解了)

说明这个 公共祖先的节点 下面的子节点肯定有 p和q。那么这个p和q 即可能都在左子树,可能都在右子树,可能分布在两边。

那么我们就从下到上的来遍历出这个树。肯定是使用后序遍历的方法。

递归找到每个叶子节点,然后从下往上寻找符合条件的 节点。

如果找到的话,对应的 p q节点,就向上返回这个节点,如果找不到就向上返回 null

然后在每个节点进行判断,看这个节点的左子树和右子树是否检查到 p q ,检查(都检查到或者检查到一个)到就标明root返回。

检查到左子树或右子树上不为null 就返回相应的 值

如果都找到了,那这个节点就是要找的公共祖先,并一直返回到最上面。

image-20221007171203787

二叉搜索树的公共祖先

image-20221007172550078

就像上面那道题一样,

但二分搜索树的节点是有特点的

我们可以很轻易的发现 从上往下遍历,找到的第一个 p.val < node.val < q.val的node时,这个节点就是索要找的值,所以就可以更方便的解决这道题,不需要把整个树全部遍历,只需要遍历复合范围条件的子树就可以image-20221007172757872