首页 > 其他分享 >无旋平衡树(范浩强Treap)平均时间复杂度证明

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

时间:2023-07-26 19:56:17浏览次数:42  
标签:lfloor log Treap 无旋 复杂度 关键字 树高

范浩强 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\).

标签:lfloor,log,Treap,无旋,复杂度,关键字,树高
From: https://www.cnblogs.com/abcc/p/17583413.html

相关文章

  • Python时间复杂度是如何衡量的?
    Python时间复杂度是如何衡量的?在计算机科学中,时间复杂度是一种用来衡量算法执行时间的度量方式。它描述了算法执行时间随输入规模增长的变化情况。时间复杂度通常用大O表示法来表示,表示算法的运行时间与输入规模的关系。在Python中,我们可以使用一些工具来计算算法的时间复杂度,例......
  • 时间复杂度和空间复杂度
    通常关注时间复杂度,对于常数阶和循环次数不变的时空复杂度,就不过多介绍了。递归的时间复杂度:对于只调用一次自身且递归次数程常数阶减少的递归,比如:voidfun(intn){if(n==0){return;}n--;returnfun(n);}它的时间复杂度是O(n),很明显它需要......
  • FHQ-Treap
    本文仅发布于此博客和作者的洛谷博客,不允许任何人以任何形式转载,无论是否标明出处及作者。前置废话fhq为什么是神。首先我们有一个正常Treap。正常Treap对于每一个值引入了一个随机的键,在节点的值形成一个BST的基础上,保证键形成一个小根堆。也就是把这一个BST做成了笛卡尔树......
  • 关于时间复杂度
    时间复杂度\(\mathcal{O}(1)<\mathcal{O}(log_2{N})<\mathcal{O}(Nlog_2{N})<\mathcal{O}(N^2)<\mathcal{O}(N^3)<\mathcal{O}(2^N)<\mathcal{O}(N!)<\mathcal{O}(N^N)\)口诀:常对幂指阶参考:【数据结构学习】算法(Algorithm)_常对幂指阶_Roy1Zz的博客-CSDN博客......
  • python算法的时间复杂度怎么算
    项目方案:计算列表中元素的平方和1.项目背景在很多应用中,我们需要对一个列表中的元素进行一些计算操作。例如,计算一个列表中所有元素的平方和。这个项目方案就是要实现这样的功能。2.问题定义给定一个列表nums,计算列表中所有元素的平方和。即,对于列表中的每个元素num,计算nu......
  • 「学习笔记」FHQ-treap
    FHQ-treap,即无旋treap,又称分裂合并treap,支持维护序列,可持久化等特性。FHQ-treap有两个核心操作,分裂与合并。通过这两个操作,在很多情况下可以比旋转treap等方便的实现一些操作。FHQ-treap与其他的平衡树相比,他最明显的优点是:它好写!!!,想象一下,在考场上,你用较短的时间写出FH......
  • 浅谈时间复杂度与空间复杂度
    算法的时间与空间复杂度(一看就懂)算法(Algorithm)是指用来操作数据、解决程序问题的一组方法。对于同一个问题,使用不同的算法,也许最终得到的结果是一样的,但在过程中消耗的资源和时间却会有很大的区别。那么我们应该如何去衡量不同算法之间的优劣呢?主要还是从算法所占用的「时间」......
  • FHQ-Treap
    简介FHQ-Treap是一种无旋转的Treap。和大多数的平衡树不一样,它并不是用旋转来维护的,而是使用了split(分裂)和merge(合并)两种操作来维护Treap的性质。实现splitsplit操作可以将一个FHQ-Treap按照某个值分裂为两个FHQ-Treap:按照权值分:将权值\(\leval\)的放到一个......
  • FHQ-Treap的详细图解
    第一部分按值分裂的FHQ-Treap按值分裂的FHQ-Treap的典型例题是P3369【模板】普通平衡树。思路FHQ-Treap是什么?FHQ-Treap是二叉搜索树的一种。比如:FHQ-Treap的思想是什么?分裂->操作->合并下面我们就来慢慢讲这些操作。分裂我们可以根据给定的\(k\)将平衡树分......
  • 最长回文子串时间复杂度为O(n)的算法
    给你一个字符串s,找到s中最长的回文子串。如果字符串的反序与原始字符串相同,则该字符串称为回文字符串示例1:输入:s="babad"输出:"bab"解释:"aba"同样是符合题意的答案。示例2:输入:s="cbbd"输出:"bb" 提示:1<=s.length<=1000s仅由数字和英文字母组成来源:力扣(LeetCo......