平衡树【Splay树】学习小记

本文介绍了平衡树的概念,强调了其防止二叉搜索树退化为链的重要性。详细阐述了二叉搜索树的性质、插入与查询操作,并讨论了平衡树中的Splay树。Splay树通过旋转操作保持平衡,同时提供了插入、查找、删除等高效操作。此外,还展示了如何在Splay树中进行区间操作,如区间翻转。最后,给出了Splay树的C++实现及例题解析。

简介

平衡树,顾名思义,平衡的搜索二叉树。

常见的平衡树都能将树的深度保持在 lg ⁡ n \lg_n lgn 的级别内,防止退化成链。

一些平衡树可以通过旋转、分裂、合并等操作完成更加高级的、二叉搜索树做不到的操作。

二叉搜索树

在讲平衡树之前,先介绍这种二叉树。

1、性质&特点

首先,规定:对于节点 x x x x x x 左子树内任一点权值< x x x 权值< x x x 右子树内任一点权值。

这一条性质也被称为 bst ( b i n a r y   s e a r c h   t r e e ) \text{bst}(binary\ search\ tree) bst(binary search tree) 性质。

由此性质可以容易地发现对于一棵二叉搜索树,如果没有插入或删除,节点的中序遍历是固定的。

当然,是在没有重复元素的前提下。至于重复元素在下面。

2、支持操作

先规定以下变量、数组:

  • tot,rt:节点数量以及根的编号。

  • v[i]:节点 i i i 的权值。

  • fa[i]:节点 i i i 的父亲编号。

  • chi[i][2]:节点 i i i 的左/右儿子。

  • cnt[i]:节点 i i i 的权值存在数量(如数列1 1 2 3,如果v[3]=1,那么cnt[3]=2)。

  • sz[i]:节点 i i i 的子树中权值数量。形式化地写,sz[i]=sz[chi[i][0]]+sz[chi[i][1]]+cnt[i]

特别地,空节点编号为0。

插入一个元素:根据 bst \text{bst} bst 性质,从根开始,向左右两侧跳。直到空位或者已有该元素大小的节点。

查询元素 x x x 的前驱:先根据 bst \text{bst} bst 性质,找到元素 x x x 所在的节点。如果 x x x 有左子树,那么前驱是它左子树内最靠右的节点;如果 x x x 没有左子树但有父亲,那前驱就是它的深度最深的、 x x x 位于右子树内的祖先。

查询元素 x x x 的后继:类似前驱。

查询元素 x x x 的排名:

  • 如果 x x x 小于当前权值,向左子树。
  • 答案加上左子树大小,如果 x x x 等于当前权值,将答案加1并返回;否则加上当前点的 cnt \text{cnt} cnt 并向右子树。

查询排名为 k k k 的数值:

  • 如果 k k k 小于左子树大小,向左子树。
  • k k k 减去左子树大小。如果 k ≤ 0 k\le0 k0 ,返回当前权值;否则向右子树。

3、死因

不难发现,如果我一直插入 1 , 2 , 3...... n 1,2,3......n 1,2,3......n ,这棵树会因此而退化成一条链。

如果离线处理,可以考虑将插入的数排序后再递归建树:

Function : d g ( l , r )                 &

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值