学习笔记——二叉平衡树(BST)

二叉平衡树(BST)

BST 是一种数据结构,用于快速查找数据。

二叉平衡树有一个非常明显的特性:对于每一个节点 \(u\),在其左边的数都比它小,在其右边待数都比它大。

每个点都有一个权值 cnt,用于存储这个数出现了几次。

在二叉平衡树上的每一个操作的时间与其树高成正比,约为 \(O(\log n)\)

BST的基本操作

插入

根据二叉平衡树的性质,新加入的数分为以下几种情况:

  • 比当前节点小,则将他下放到左儿子。
  • 等于这个节点,则将这个节点的 \(cnt+1\)
  • 否则则下放到右儿子。

最后如果没有节点就新建一个节点,并且根据大小关系归在父亲节点的左或右儿子,将节点的 \(cnt\) 设为 \(1\)

删除

和插入是相反操作,规则同插入操作,但当等于当前结点值的时候,要分两种情况:

  • 当前结点的 \(cnt\)\(>1\),即当前节点存在不止一个数,直接将 \(cnt-1\) 即可。
  • 当前结点 \(cnt\)\(1\),即只有一个这样的节点,这时候如果这个点是叶子节点(下面没有儿子,直接将这个点的 \(cnt\) 设成 \(0\),编号直接删除。如果这个节点下面还有儿子,就把下面两个元素中的任意一个元素所有变量赋值到这个位置,并且递归删除下面的点,操作同上。

查找排名为 \(x\) 的元素

根节点的排名取决于左子树的大小。

  • 当左子树大小大于等于 \(x\),则这个元素位于左子树
  • 当左子树大小位于 \([x-cnt, x-1]\) 之间,则这个元素位于根节点
  • 否则,这个元素位于右子树

查找元素 \(x\) 的排名

相当于搜索 \(x\),在遍历右子树时需要加上左子树以及根节点的大小。

BST 的时间复杂度约为 \(O(\log n)\),但是由于其特殊的性质,最坏情况下可以退化成一条链,这时候,复杂度将会退化成 \(O(n)\),有超时风险。这时候就需要优化,优化方法有 Treap 和 Splay 等。

posted @ 2024-07-11 12:39  Network_Flow  阅读(65)  评论(0)    收藏  举报