使用均攤分析證明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處理不掉,會使複雜度爆掉。