Loading [MathJax]/jax/output/CommonHTML/jax.js

使用均摊分析证明Splay复杂度

使用均摊分析证明Splay复杂度

(PS:终于知道了二叉搜索树(binarysearchtree)为什么叫BST。)
平衡树的一种,靠着旋转来保证复杂度。

怎么旋转?这已经说烂了,我比较关心的是splay的复杂度怎么证明,和为什么一定要使用双旋操作。

(PS:Splay居然是Tarjan发明的)
本篇博客证明思路提供于Splay复杂度的证明
但是我看不懂然后借鉴了伸展树(Splay)复杂度证明
但是我看不懂然后借鉴了均摊分析 学习笔记
但是我看不懂然后借鉴了均摊分析简介
吐了
算法导论yyds

######以下证明并不严谨######

均摊分析

Splay证明的核心是均摊分析中的势能分析(其他分析方法见均摊分析简介

ci为第i次操作的实际代价。ϕi是第i次操作之后的势能。

ci+ϕiϕi1是第i次操作的均摊代价。

n次操作的均摊代价为ai=ni=1(ci+ϕiϕi1)=ni=1ci+ϕnϕ0

如果我们设的势能ϕi都是不小于0的数,那么ϕnϕ0>=0。特别地一般令ϕ0=0

如果我们算出了总均摊代价的上界,我们就可以得出真实代价的上界。

朴实地说:真实代价<均摊代价均摊代价上界。

这样看均摊代价的上界一定是比真实代价的上界好求的,为什么加了势能之后反而好求了呢?带着问题思考。

Splay的均摊分析

μx=log2(size(x))其中size(x)代表x子树的大小。

ϕx=ni=1μ(i),任何时候ϕx显然是小于nlogn的,这个上界十分宽松。

zig(zag)的分摊分析

因为两操作等价,这里只分析zig

显然均摊代价a(i)=1+μ(x)+μ(y)μ(x)μ(y)

这里的1并不是真的1,而是代表这一次旋转操作的真实代价,是一个常数。(下面证明中出现的1也是一样的)

μ(y)=μ(x) a(i)=1+μ(y)μ(x)

μ(y)<μ(x) a(i)<1+μ(x)μ(x)

zig-zig(zag-zag)的分摊分析

a(i)=μ(x)+μ(y)+μ(z)μ(x)μ(y)μ(z)+1

μ(z)=μ(x) a(i)=μ(y)+μ(z)μ(x)μ(y)+1

μ(y)<μ(x) , μ(x)<μ(y) a(i)<1+μ(x)+μ(z)2μ(x)

先把式子放在这里,转去证明μ(x)+μ(z)2μ(x)<1

μ(x)+μ(z)2μ(x)=log(size(x)size(x))+log(size(z)size(x))=log(size(x)size(z)size(x)2)

由上图可知size(x)=size(x)+size(z)+1size(x)>size(x)+size(z)

原式<log(size(x)size(z)(size(x)+size(z))2)<log(size(x)size(z)2size(x)size(z))=1

1+2μ(x)μ(x)μ(z)>0

a(i)加上这个正数显然有a(i)<1+μ(x)+μ(z)2μ(x)1+2μ(x)μ(x)μ(z)

这里注意了:式子中两个1不一样,第一个1是代表这个操作的真实代价是一个常数,第二个1就是实实在在的1,但是把这个1和势能的单位同时增大之后可以把前面的代表常数的1消掉。

a(i)<3(μ(x)μ(x))

zig-zag(zag-zig)的分摊分析

用跟上面几乎完全一样的方法可以得到:

a(i)<2(μ(x)μ(x))

因为zig(zag)操作一个splay操作中只会用一遍这样整个一次splay操作地均摊复杂度为:
1+n(μ(xi)μ(xi))=1+μ(root)μ(x)近似为logn

所以均摊复杂度为logn

这也解释了为什么不能一直单旋,因为那个常数1处理不掉,会使复杂度爆掉。

PS:我感觉这个证明大有问题,但又不知道哪里有问题

posted @   Xu-daxia  阅读(241)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示