1. 程式人生 > 其它 >使用均攤分析證明Splay複雜度

使用均攤分析證明Splay複雜度

使用均攤分析證明Splay複雜度

(PS:終於知道了二叉搜尋樹(\(binary search tree\))為什麼叫\(BST\)。)
平衡樹的一種,靠著旋轉來保證複雜度。

怎麼旋轉?這已經說爛了,我比較關心的是\(splay\)的複雜度怎麼證明,和為什麼一定要使用雙旋操作。

(PS:\(Splay\)居然是\(Tarjan\)發明的)
本篇部落格證明思路提供於Splay複雜度的證明
但是我看不懂然後借鑑了伸展樹(Splay)複雜度證明
但是我看不懂然後借鑑了均攤分析 學習筆記
但是我看不懂然後借鑑了均攤分析簡介
吐了
演算法導論yyds

######以下證明並不嚴謹######

均攤分析

\(Splay\)

證明的核心是均攤分析中的勢能分析(其他分析方法見均攤分析簡介

\(c_i\)為第i次操作的實際代價。\(\phi_i\)是第\(i\)次操作之後的勢能。

\(c_i+\phi_i-\phi_{i-1}\)是第\(i\)次操作的均攤代價。

\(n\)次操作的均攤代價為\(a_i=\sum_{i=1}^n(c_i+\phi_i-\phi_{i-1})=\sum_{i=1}^nc_i+\phi_n-\phi_{0}\)

如果我們設的勢能\(\phi_i\)都是不小於0的數,那麼\(\phi_n-\phi_0>=0\)。特別地一般令\(\phi_0=0\)

如果我們算出了總均攤代價的上界,我們就可以得出真實代價的上界。

樸實地說:真實代價\(<\)均攤代價\(\leq\)均攤代價上界。

這樣看均攤代價的上界一定是比真實代價的上界好求的,為什麼加了勢能之後反而好求了呢?帶著問題思考。

Splay的均攤分析

\(\mu_x=log_2(size(x))\)其中\(size(x)\)代表x子樹的大小。

\(\phi_x=\sum_{i=1}^n\mu(i)\),任何時候\(\phi_x\)顯然是小於\(nlogn\)的,這個上界十分寬鬆。

zig(zag)的分攤分析

因為兩操作等價,這裡只分析zig

顯然均攤代價\(a(i)=1+\mu(x')+\mu(y')-\mu(x)-\mu(y)\)

這裡的1並不是真的1,而是代表這一次旋轉操作的真實代價,是一個常數。(下面證明中出現的1也是一樣的)

\(\because \mu(y)=\mu(x') \ \therefore a(i)=1+\mu(y')-\mu(x)\)

\(\because \mu(y')<\mu(x') \ \therefore a(i)<1+\mu(x')-\mu(x)\)

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

\(a(i)=\mu(x')+\mu(y')+\mu(z')-\mu(x)-\mu(y)-\mu(z)+1\)

\(\because \mu(z)=\mu(x') \ \therefore a(i)=\mu(y')+\mu(z')-\mu(x)-\mu(y)+1\)

\(\because \mu(y')<\mu(x') \ ,\ \mu(x)<\mu(y) \ \therefore a(i)<1+\mu(x')+\mu(z')-2\mu(x)\)

先把式子放在這裡,轉去證明\(\mu(x)+\mu(z')-2\mu(x')<-1\)

\(\mu(x)+\mu(z')-2\mu(x')=log(\frac{size(x)}{size(x')})+log(\frac{size(z')}{size(x')})=log(\frac{size(x)size(z')}{size(x')^2})\)

由上圖可知\(size(x')=size(x)+size(z')+1\)\(size(x')>size(x)+size(z')\)

\(\therefore\)原式\(<log(\frac{size(x)size(z')}{(size(x)+size(z'))^2})<log(\frac{size(x)size(z')}{2size(x)size(z')})=-1\)

\(\therefore -1+2\mu(x')-\mu(x)-\mu(z')>0\)

\(a(i)\)加上這個正數顯然有\(a(i)<1+\mu(x')+\mu(z')-2\mu(x)-1+2\mu(x')-\mu(x)-\mu(z')\)

這裡注意了:式子中兩個1不一樣,第一個1是代表這個操作的真實代價是一個常數,第二個1就是實實在在的1,但是把這個1和勢能的單位同時增大之後可以把前面的代表常數的1消掉。

\(a(i)<3(\mu(x')-\mu(x))\)

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

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

\(a(i)<2(\mu(x')-\mu(x))\)

因為zig(zag)操作一個splay操作中只會用一遍這樣整個一次splay操作地均攤複雜度為:
\(1+\sum^n (\mu(x'_i)-\mu(x_i))=1+\mu(root)-\mu(x)\)近似為\(logn\)

所以均攤複雜度為\(logn\)

這也解釋了為什麼不能一直單旋,因為那個常數1處理不掉,會使複雜度爆掉。