Treap 树高的一种证明
_xm_
·
·
算法·理论
我们考虑笛卡尔树的建树过程:将 n 个节点按键值从小到大排序,此时选出优先级最小的节点 i 作为根节点,剩下 [1,i-1], [i+1,n] 的节点递归建树。
优先级最小的节点等概率的出现在 [1,n] 中,令 f(n) 为 Treap 的期望树高,我们可以列出:
f(n)= \frac{1}{n} \sum_{i=1}^{n} \max\{f(i-1), f(n-i)\} + 1
显然 f(0)=0,f(1)=1。
Proof
我们考虑数学归纳法,假设存在常数 c,d>0,使得对所有 k \in [1,n),有 f(k)\le c \ln k + d,目标是证 f(n)\le c \ln n + d。
注:需要注意的是,\ln 0 是未定义的,我们可以在表达式中省略 f(0) 来规避这个问题。
f(n)= \frac{1}{n} \sum_{i=1}^{n} \max\{f(i-1), f(n-i)\} + 1
由于 f(n) 单调递增,\max 取较大的那个即可只考虑一半:
f(n)\le 1+\frac{2}{n} \sum_{i=\lfloor \frac{n}{2} \rfloor}^{n-1} f(i)
当 n 为奇数时中位数 i = \lfloor \frac{n}{2} \rfloor+1 对应的项 \frac{1}{n} f(\lfloor \frac{n}{2} \rfloor) 会被计算两次。
由于 \ln x 单调递增,所以 \sum_{i=m}^n \ln i < \int_{m}^{n+1} \ln x \, dx,用积分近似求和:
\sum_{i=\lfloor \frac{n}{2} \rfloor}^{n-1} f(i) \le \sum_{i=\lfloor \frac{n}{2} \rfloor}^{n-1} (c \ln (i)+d) < \int_{\frac{n}{2}}^{n} (c\ln(x)+d) \, \mathrm dx
计算积分:
\int_{n/2}^{n} (c \ln x + d) \, \mathrm dx = \frac{n}{2}(c \ln 2n - c + d)
从而:
f(n)\le 1+\frac{2}{n} \sum_{i=\lfloor \frac{n}{2} \rfloor}^{n-1} f(i) < 1 + \frac{2}{n} \cdot \frac{n}{2}(c \ln 2n - c + d) = c\ln 2n - c + d + 1
为使不等式 f(n) < c\ln 2n - c + d + 1 \le c \ln n + d 成立,解不等式:
c \ln 2n - c + d + 1 \le c \ln n + d
c (\ln 2 - 1) + 1\le 0
c \ge \frac{1}{1-\ln 2} \approx 3.259
当 n=1 时,f(1)=1。只要取 d \ge 1 就有 f(1)\le c \ln 1 + d。
综上,我们得到了比较紧的上界 f(n)\le \frac{1}{1-\ln 2} \ln n + 1,因此 Treap 树高的期望为 O(\log n)。
附一张数值表:
| n |
f(n) |
\frac{1}{1-\ln 2} \ln n + 1 |
| 10^0 |
1.0000 |
1.0000 |
| 10^1 |
5.6042 |
8.5039 |
| 10^2 |
12.6187 |
16.0077 |
| 10^3 |
20.0703 |
23.5116 |
| 10^4 |
27.5689 |
31.0155 |
| 10^5 |
35.0723 |
38.5194 |
| 10^6 |
42.5761 |
46.0232 |
| 10^7 |
50.0800 |
53.5271 |
| 10^8 |
57.5838 |
61.0310 |