Splay Trees
Splay Trees的重點整理。
定義
-
Splay Tree:一種二元搜尋樹 (BST)。
-
每次執行 Search / Insert / Delete 操作後,會對相關節點做 splay (伸展),也就是透過一連串旋轉,將該節點移到樹根。
-
目標:利用平攤分析 (amortized analysis),保證平均操作時間為 O(log n)。
Splay Tree Lemma 與 Theorem 證明整理
Lemma:單次 splay 的 amortized cost
敘述 對於起始節點 \(q\),單次 splay 的平攤成本至多為 \(3(\log_2 n - r(q)) + 1\)
位能法公式
其中:
- \(r(i) = \log_2 s(i)\),\(s(i)\) 是以節點 \(i\) 為根的子樹大小。
- 位能 \(\Phi = \sum_i r(i)\)。
分情況討論
1. Zig
- \(q\) 為 root 或無祖父。
- 成本 \(=1\),位能不變。
- Amortized cost \(=1\)。
2. Zig(有父無祖父)
- 實際成本 = \(1\)。
- 位能變化:\(\Delta \Phi = \Phi_i - \Phi_{i-1} = (r'(p) + r'(q)) - (r(p) + r(q))\)。
- 單調性:
- \(p\) 的子樹變小:\(s'(p) \le s(p) \;\Rightarrow\; r'(p) \le r(p)\)。
- \(q\) 的子樹變大:\(s'(q) \ge s(q) \;\Rightarrow\; r'(q) \ge r(q)\)。
- 由性質可得:\(\text{Amortized cost}=1+\Delta \Phi \leq 1 + (r'(q) - r(q))\)。
3. Zig-Zig / Zig-Zag
- 影響節點 \(q, p, gp\)。
- 位能變化:
- 分析可得:
綜合各情形得 Access Lemma:\(\text{amortized cost} \le 3\big(r(\text{root}) - r(q)\big) + 1 \le 3(\log_2 n - r(q)) + 1\)。因此為 \(O(\log n)\),且給出更精確的常數界。
Theorem 10.1:n 次操作的總時間
敘述 在一棵空的 splay tree 上進行 \(n\) 次操作(search, insert, delete),總時間為 \(O(n \log n)\)。
推導
- 單次操作時間:
- n 次操作總和:
- 因為 \(\Phi_0 = 0\) 且 \(\Phi_n \geq 0\):
- 根據 Lemma:
結論 : n 次操作的總時間複雜度為 \(O(n \log n)\)。
Splay 起點
-
Search:找到的節點。
-
Insert:新插入的節點。
-
Delete:被刪除節點的父節點(若存在),若刪除的是根則為
NULL。 -
那麼做完所有操作都要做
Splay,並且觀察gp和p是調整的哪種 case,調整的 root
Splay 操作規則
-
Zig
-
條件:節點
q有父節點p,但沒有祖父節點gp。 -
動作:對
p和q做單次旋轉。 -
註解:只需一步旋轉就能將節點提到根.
-
-
Zig-Zig
-
條件:節點
q有父節點p和祖父節點gp,且q和p在同一方向(LL 或 RR)。 -
動作:先旋轉
gp-p,再旋轉p-q。 -
註解:連續兩次同方向旋轉,像「之」字往同一邊彎,稱為 Zig-Zig。
-
-
Zig-Zag
-
條件:節點
q有父節點p和祖父節點gp,但q和p在不同方向(LR 或 RL)。 -
動作:先旋轉
p-q,再旋轉gp-q。 -
註解:方向交錯,先往一邊再往另一邊,像「之」字折返,稱為 Zig-Zag。
-
範例
| 節點 | \(s(i)\) 計算 | \(r(i)\) 計算 |
|---|---|---|
| 5 | \(s(5)=1+\lvert e\rvert+\lvert f\rvert=1\) | \(r(5)=\log_2(1)=0.0000\) |
| 4 | \(s(4)=1+\lvert d\rvert+s(5)=1+0+1=2\) | \(r(4)=\log_2(2)=1.0000\) |
| 3 | \(s(3)=1+\lvert c\rvert+s(4)=1+0+2=3\) | \(r(3)=\log_2(3)=1.5850\) |
| 6 | \(s(6)=1+s(3)+\lvert g\rvert=1+3+0=4\) | \(r(6)=\log_2(4)=2.0000\) |
| 7 | \(s(7)=1+s(6)+\lvert h\rvert=1+4+0=5\) | \(r(7)=\log_2(5)=2.3219\) |
| 2 | \(s(2)=1+\lvert b\rvert+s(7)=1+0+5=6\) | \(r(2)=\log_2(6)=2.5850\) |
| 8 | \(s(8)=1+s(2)+\lvert i\rvert=1+6+0=7\) | \(r(8)=\log_2(7)=2.8074\) |
| 9 | \(s(9)=1+s(8)+\lvert j\rvert=1+7+0=8\) | \(r(9)=\log_2(8)=3.0000\) |
| 1 | \(s(1)=1+\lvert a\rvert+s(9)=1+0+8=9\) | \(r(1)=\log_2(9)=3.1699\) |
複雜度比較
| 資料結構 | 調整方式 | 單次最壞情況 | 平攤時間 |
|---|---|---|---|
| AVL Tree | 高度平衡 | \(O(log n)\) | \(O(log n)\) |
| Red-Black Tree | 弱平衡 | \(O(log n)\) | \(O(log n)\) |
| Splay Tree | 自我調整 | \(O(n)\) | \(O(log n)\) |
- splay tree \(O(n)\) 是樹高 \(n\)
應用
-
適合存取 局部性高 的資料(快取、符號表、字典)。
-
不需額外存平衡資訊,比 AVL / RB-Tree 簡單。