splay 的复杂度分析
势能分析
在数据结构问题中,我们往往难以估计第 i 次的实际时间开销 ti。
所以我们要引入一些势能分析的概念:
- 设 ϕi 表示:第 i 次操作过后,数据结构的势能值。
- 记 ai=ti+ϕi−ϕi−1,即第 i 次操作的均摊时间。
注意:确定势能值的势函数是需要我们自己确定的,寻找一个优秀的势函数往往可以更容易解决问题。
假设执行了 m 次操作,那么总的实际时间为:
∑1≤i≤mti=∑1≤i≤mai+ϕ0−ϕm
所以知道了 ai,ϕ 的复杂度就可以求出总的实际时间了。
在 splay 中,我们取这样的一个势函数:
- 设当前状态下,节点 x 的势能值 F(x)=logsizex。
- 设当前状态下,整棵 splay 的势能值 ϕ=∑1≤i≤nF(i)。
接下来要证明的结论是:
ai≤3(F(x′)−F(x))+1=O(lognsizex)=O(logn)
其中 F(x),F(x′) 分别表示伸展 x 前和伸展 x 后节点 x 的势能值。
双旋 splay 的三种旋转
来回顾一下双旋 splay 的三种旋转:
-
当 x 的父亲 p 是根节点时,直接 zig/zag x。
-
当 x 和上两代祖先位于一条链上:先 zig/zag p,再 zig/zag x。
-
当 x 和上两代祖先分叉时:先 zig/zag x,再 zig/zag x。
第一种旋转的均摊分析(以 zig 为例)

分析:
-
时间开销:旋转了一次。
-
势能变化:子树大小只有节点 x,y 发生了变化,故只有节点 x,y 的势能值发生了变化。
所以可以得到:
azig=1+F(x′)+F(y′)−F(x)−F(y)=1+F(y′)−F(x)
适当放缩得:
azig≤3(F(x′)−F(x))+1
第二种旋转的均摊分析(以 zig-zig 为例)

分析:
- 时间开销:旋转了两次。
- 势能变化:子树大小只有节点 x,y,z 发生了变化,故只有节点 x,y,z 的势能值发生了变化。
所以可以得到:
azig-zig=2+F(x′)+F(y′)+F(z′)−F(x)−F(y)−F(z)=2+F(y′)+F(z′)−F(x)−F(y)
然后你发现这个多出来的 2 非常令人不爽。
注意到:
F(x)+F(z′)−2⋅F(x′)≤logsizex⋅sizez′size2x′≤−2
(均值不等式即可证明,大家都会。)
然后将这两个式子合并可以得到:
azig-zig≤2⋅F(x′)+F(y′)−2⋅F(x)−F(y)
适当放缩得:
azig-zig≤3(F(x′)−F(x))
第三种旋转的均摊分析(以 zig-zag 为例)

分析:
- 时间开销:旋转了两次。
- 势能变化:子树大小只有节点 x,y,z 发生了变化,故只有节点 x,y,z 的势能值发生了变化。
所以可以得到:
azig-zag=2+F(x′)+F(y′)+F(z′)−F(x)−F(y)−F(z)=2+F(y′)+F(z′)−F(x)−F(y)
注意到:
F(x)+F(z′)−2⋅F(x′)≤logsizex⋅sizez′size2x′≤−2
然后将这两个式子合并可以得到:
azig-zag≤2⋅F(x′)+F(y′)−2⋅F(x)−F(y)
适当放缩得:
azig-zag≤3(F(x′)−F(x))
顺次组合所有操作
在伸展一个节点 x 的时候,将每次旋转的贡献式子连接起来,消除相邻的项,可以得到:
ai≤3(F(x′)−F(x))+1=O(lognsizex)=O(logn)
- 因为 ai=O(logn),所以 ∑1≤i≤mai=O(mlogn)。
- 因为 0≤ϕ≤nlogn,所以 ϕ0−ϕm=O(nlogn)。
于是 splay 的时间复杂度即为 O((n+m)logn)。
泛滥河水将我冲向你的心头,不停流 ......
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探