Splay 学习笔记

为了 LCT 制造了一个 Splay ……

Splay 还是一种二叉排序树。我们想让他支持查询结点,删除结点等等。但是普通 BST 复杂度难以保证,于是 Splay 出现了。

【引入】

Splay 的思想和并查集的路径压缩类似。并查集的路径压缩允许出现一两次复杂度高的操作,但是经历过一次后就不会再有第二次了。

Splay 的基本思想就是在操作一个结点时,直接把这个结点放到根结点上。

【单旋与双旋】

区分三种操作:单旋、双旋、把某个结点转到根。

回想以前的数据结构,在操作一个结点时需要改变结点的位置的,旋转 Treap 的旋转操作非常具有特点。

单旋:zig(右旋) 和 zag(左旋)。

Splay 的特殊之处就在于,我们发明了一种 "双旋" 操作,一次操作可以让一个结点和他的祖父交换位置,且不改变二叉排序树的性质。

双旋的理念也很简单:要上升两层,那就做两次单旋。两次单旋共 2×2=4 种方案,衍生出 4 种双旋。

  1. zig-zig,即两次都是右旋操作。

    左侧的 x 是我们要转到根结点的结点,但是在这一次双旋里面,我们只考虑让他转到他的祖父结点 g 处。px 的父亲。

    右侧上下是两种旋转的方式:一种是转两次 x,一种是先转 p 再转 x。Splay 在进行这种双旋时我们采取下面那种,具体原因后面会说。

  2. zag-zag,先转 p 后转 x

  3. zag-zig,转两次 x

    其实这种情况只能先转 x,如右侧,如果先对 p zag,x 无法上升。

  4. zig-zag,转两次 x

zag-zig 和 zig-zag 是只能转两次 x 的,没有疑问;但是 zig-zig 和 zag-zag 为什么要先转 p?这涉及到复杂度分析。

【复杂度分析】

【概念】

算 Splay 的复杂度首先要认识到什么是 "分摊复杂度":单次操作可能很慢,多次操作平均很快。

其次是 "势能":这是一个物理的概念。

当一个物体在一个高度,那当这个物体下落的时候,位置本身就会赋予物体下落的能量,我们称其为重力势能。高度越高,重力势能越大。

这个概念有什么特殊之处?当一个物体从位置 A 到了位置 B,中间可能有各种乱七八糟的移动,但其重力势能的变化量,只有位置 B 与位置 A 的高度差产生的重力势能。

那这和复杂度分析有什么关系?

【势能分析法】

我们为了证明,人为定义一个起始势能 S 和结束势能 T

不妨每次操作是 t1,t2,,tm

总时间 =t1+t2++tm=ti+(TS)(TS)

我们希望 TS 是个不太大的数,同时希望可以把 TS 拆成 k1+k2++km,而且 ti+ki 单次操作复杂度上限 x

如果我们真的设计出一个这样的势能函数,ti+(TS)(TS)=(TS)+(ti+ki)(TS)+mx

(对较大的 ti 放一个较小的 ki,对较小的 ti 放一个较大的 ki,多退少补,总和是 TS

目标是让 TSO(nlogn) 级别,让 xO(logn) 级别。这样总时间就是 O(nlogn+mlogn)。均摊每一次是 O(nmlogn+logn),一般就能直接视作 O(logn) 的了。


sii 子树规模,pi=logsii 的势能。

S=pi,T=pi

这里指的是 Splay 这颗 BST 在经历操作前和经历操作后。

一个结点的 si 显然 n,所以 S,T 显然都 nlogn,则 (TS)nlogn。接下来的任务就是把 (TS) 拆成 mki

我们认为一次单旋操作是 "1 次" 操作。

结论:让 x 转上祖父的双旋操作次数

posted @   FLY_lai  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示