无旋平衡树(范浩强Treap)平均时间复杂度证明

发布时间 2023-07-26 19:53:38作者: abcc!

范浩强 Treap 是一种应用广泛的数据结构(可参考 OI_Wiki),然而网上难以找到比较严谨的复杂度证明. 本文将严格证明 \(n\) 个结点的 Treap 的期望树高\(\Theta(\log n)\),由于一次分裂或合并操作的递归深度恰为树高,这便说明了一次操作的平均时间复杂度为 \(\Theta(\log n)\).

首先,由于 \(n\) 个点的二叉树的树高显然不小于 \(\log_2 n\),只须证明复杂度上界 \(O(\log n)\). 不妨假设 \(n\) 个结点的权值互不相同. 一个 Treap 是以随机权值为堆关键字、维护数集为 BST 关键字的笛卡儿树. 因此,只要随机权值实现确定好,Treap 的形态就唯一确定了,与点的插入顺序无关. 我们的问题变成:随机生成一个长度为 \(n\) 的排列,其笛卡儿树(下标为堆关键字、值为 BST 关键字)的期望树高是多少?我们设答案为 \(E_n\).

考虑笛卡儿树的根,它代表排列的第一个元素,因此其 BST 关键字在 \(1\sim n\) 中均匀随机. 设这个值是 \(i\). 由于左子树的 BST 关键字都比 \(i\) 小,右子树的都比 \(i\) 大,因此左右子树的大小分别为 \(i-1\)\(n-i\). 左右两边是独立的,其期望树高分别是 \(E_{i-1}\)\(E_{n-i}\),整棵树的期望树高是较大者加 \(1\). 因此

\[E_n=1+\dfrac1n\sum_{i=1}^n\max\{E_{i-1},E_{n-i}\}. \]

显然,\(E_n\) 关于 \(n\) 单调增加,上式可化简成

\[E_n=1+\dfrac1n\left(2S_{n-1}-S_{\lfloor(n-2)/2\rfloor}-S_{\lfloor(n-1)/2\rfloor}\right), \]

其中 \(S_n=\sum_{i=1}^nE_i\). 以 \(E_n=S_n-S_{n-1}\) 代入上式,便可得到 \(S_n\) 的递推式

\[S_n=\dfrac{n+2}nS_{n-1}-\dfrac1nS_{\lfloor(n-2)/2\rfloor}-\dfrac1nS_{\lfloor(n-1)/2\rfloor}+1. \]

由于 \(n/2\) 项的存在,该递推式很难直接求解,但我们只须说明 \(S\) 的增长速度是 \(O(n\log n)\)(从而其差分 \(E_n\) 的增长速度是 \(O(\log n)\)). 下面采用代入法证明:

用数学归纳法. 设 \(\forall k<n\) 已经有 \(S_k<ck\ln k\),其中 \(c\) 是事先选定的常数. 省事起见,我们忽略两个“下取整”下标带来的微小区别,将它们都视作 \(n/2\).

\[\begin{align*} S_n&=\dfrac{n+2}nS_{n-1}-\dfrac2nS_{n/2}+1 \\&<\dfrac{n+2}nc(n-1)\ln(n-1)-\dfrac2nc\dfrac{n}2\ln\dfrac{n}2+1&\text{(归纳假设)} \\&=c\left(\dfrac{n^2+n-2}n\ln(n-1)-\ln\dfrac{n}2\right)+1 \\&=c\left(\left(n+1-\dfrac2n\right)\left(\ln n-\ln\dfrac{n}{n-1}\right)-\ln n+\ln2\right)+1&\text{(对数运算法则)} \\&=c\left(n\ln n-n\ln\dfrac{n}{n-1}-\ln\dfrac{n}{n-1}-\dfrac2n\ln(n-1)+\ln2\right)+1 \\&<c\left(n\ln n-n\ln\dfrac{n}{n-1}+\ln2\right)+1&\text{(去掉两个负项)} \\&<c\left(n\ln n-1+\ln2\right)+1&\text{(两个重要极限之一)} \\&=cn\ln n+(1-c(1-\ln2)). \end{align*} \]

\(c=\dfrac1{1-\ln2}\approx3.26\),最后的式子便等于 \(cn\ln n\),于是有 \(S_n<cn\ln n\). 证毕.

有意思的是,上面证明过程中的三步放缩都是紧的(略去的两个负项在 \(n\rightarrow+\infty\) 时均趋向于 \(0\)). 因此这给出 \(\Theta(\log n)\) 中对数底数的大致估计:它大约是 \(\dfrac{\mathrm{e}}2\approx1.36\).