treap/FHQ treap的复杂度证明
感觉是个比较有意思 虽然可能没什么用 的东西。
首先我们约定我们将会操作 \(n\) 个节点,同时这 \(n\) 的节点的 \(\text{val}\)(权值)和 \(\text{key}\)(键值)确定。这仅仅是方便我们接下来的证明,节点的权值与键值到底是多少并不重要。
考虑到键值是随机值,一般来说几乎不可能碰撞,即使碰撞了也最多只会有 \(O(1)\) 个节点,可以忽略,故可假定键值两两不同。
接下来的证明基于如下性质:
对于一棵树堆,若其节点的 \(\text{key}\)(键值)两两不同,则无论按何顺序插入节点,最终树堆的形态必定唯一确定。
证明:首先键值两两不同的时候树堆就是笛卡尔树,而笛卡尔树的形态必定固定。证毕
好吧其实也可以直接理解:首先根节点必定固定(必定是键值最大的那个),而其余节点属于根节点的左子树还是右子树也是确定的(按照权值大小分),归纳证明即可。
显然 treap 和 fhq treap 都是在维护树堆,只不过维护方式略有不同而已,操作结束后平衡树的形态必定相同。考虑上文的性质,对一棵 treap 进行若干次分裂再合并后,平衡树的形态仍然不变。同理,在一棵 treap 内删除一个节点,平衡树的形态就等价于顺次向一棵空树内插入剩余的 \(n - 1\) 个节点。
同时,每种操作的时间复杂度都不会大于树高,这个是比较显然的。于是我们只需要证明,有 \(n\) 个节点的 treap 的树高是 \(O(\log n)\) 的即可。
考虑 treap 的根节点,其必定是某种比较方式下 \(n\) 个节点中键值最大的一个。而因为键值是随机值,大小与权值无关,故根节点的权值在 \(n\) 个节点中从大到小的位置必定是在 \(1\) 到 \(n\) 内均匀分布的。我们发现这个过程等价于快速排序(每次随机选定一个元素作为基准值,再按照基准值将整个数组分为两部分)。而快速排序的递归树高度是有保证的,故 treap 的时间复杂度正确。
或者来尝试证明一下(快速排序的递归树高度)?
-
递归树的期望高度为 \(O(\log n)\)
归纳证明,首先当 \(n \le 1\) 时显然成立,当 \(n > 1\) 时,设 \(h_n\) 是大小为 \(n\) 的递归树的期望高度,则有
\(h_n = 1 + \frac{1}{n} \sum\limits_{i = 0}^{n - 1} \max(h_{i}, h_{n - i - 1}) = 1 + \frac{2}{n} \sum\limits_{i = \lfloor \frac{1}{n} \rfloor}^{n - 1} h_{i}\)
故有
\(h_n \le 1 + \frac{2}{n} \sum\limits_{i = 1}^{n - 1} h_i = 1 + \frac{2}{n} \sum\limits_{i = 1}^{n - 1} \log i = 1 + \frac{2}{n} \log ((n - 1)!)\)
前面的常数项 \(1\) 和分子上的 \(2\) 可以忽略。而后面的部分是一个经典的式子,根据斯特林近似,我们知道它就是 \(O(\log n)\) 的,故期望高度为 \(O(\log n)\) 得证。
-
递归树的最小高度为 \(O(\log n)\)
考虑上面的式子,显然 \(h_n = 1 + h_{\lfloor \frac{2}{n} \rfloor}\) 的时候取最小值,也是 \(O(\log n)\)。
-
递归树的深度的分布主要集中在 \(O(\log n)\) 附近
暂时还不会。/kel

浙公网安备 33010602011771号