Treap 树高的一种证明

· · 算法·理论

我们考虑笛卡尔树的建树过程:将 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)=0f(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