【笔记】Splay 详细解读


简介

Splay 是一种平衡树,并且是一棵二叉搜索树(BST)。

它满足对于任意节点,都有左子树上任意点的值 < 当前节点的值 < 右子树上任意点的值。

优点:支持多种操作。
缺点:常数较大。

单次操作均摊复杂度 O ( log ⁡ n ) O(\log n) O(logn)

(注:关于 Splay 单次操作均摊复杂度的证明见 OI-Wiki)

Splay 基于旋转操作维护树的平衡。旋转分为左旋 (zag) 和右旋 (zig)。

旋转,即在保证平衡树中序遍历不变的前提下,改变整个树的深度。

右旋

zig

对于单次操作 zig(a) ,将节点 a a a 左儿子的左儿子( c c c)接到 a a a 的左儿子处,将 c c c 的右儿子接到 b b b 的左儿子,将 c c c 的右儿子改为 b b b

这样,我们完成了一次右旋操作,操作前后, a a a 左子树的中序遍历都为 DcEbF

左旋

zag

左旋即右旋的逆过程,将每一步反过来即可。


核心思想

每次操作之后,都将被操作的节点旋转至根节点。

这个和均摊时间复杂度有关。

操作

a. Splay

每次调用函数 splay(x, k) 表示把点 x x x 旋转至点 k k k 下方。

特别地,当调用 splay(x, 0) 时,表示把点 x x x 旋转至根节点。

有两种情况:

  1. x , y , z x, y,z x,y,z 成一条链

1

  1. x , y , z x,y,z x,y,z 不成一条链

2

b. 插入
  • 根据 BST 性质,找到该元素所在位置并新建节点。插入后将该节点旋转至根节点。
  • 当要求将一个序列插到 y y y 的后面时:
    1. 找到 y y y 的后继 z z z
    2. y y y 转到根。(splay(y, 0);
    3. z z z 转到 y y y 的下方。(splay(z, y);)由于 z > y z>y z>y,所以 z z z y y y 的右儿子。
    4. 显然,此时将要插入的序列接到 z z z 的左儿子(∅)上即可。

ins

c. 删除
  • 删除一段区间 [ l , r ] [l,r] [l,r]
    1. 分别找到 l l l 的前驱 p p p r r r 的后继 q q q
    2. p p p 转到根节点。
    3. q q q 转到 p p p 下方。由于 p < q p<q p<q,所以 q q q p p p 的左儿子。
    4. 显然,要删除的区间就是点 p p p 的整个左子树。直接变没即可。

信息的维护

以模板题 AcWing 2437. Splay 为例。

本题要求我们进行区间翻转操作。

因此维护两个值&

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星河依旧长明

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值