介绍
树堆,在数据结构中也称Treap,是指有一个随机附加域满足堆的性质的二叉搜索树,其结构相当于以随机数据插入的二叉搜索树。其基本操作的期望时间复杂度为O(log2n)O(\log_2n)O(log2n)。
对于插入
给节点随机分配一个优先级,先和二叉排序树的插入一样,先把要插入的点插入到一个叶子上,然后跟维护二叉平衡树一样,如果当前节点的优先级比父亲大就旋转,如果当前节点是父亲的左儿子就右旋,如果当前节点是父亲的右儿子就左旋。
通常来说,优先级是伴随着访问次数来改变的。
证明
在这里我们先假设优先级的分布是稠密的。
如果不是稠密的,可以通过映射来构造一个稠密的分布:
把优先级从小到大排序,然后把优先级直接用序号代替。这样就得到了一个稠密的分布
设我们要插入的节点的优先级为XXX,treap里面最大的优先级为LimitLimitLimit,简称LLL。
首先,如果X≥LX \ge LX≥L,那么就不用旋转。
所以我们讨论X≤LX \le LX≤L 的情况
我们可以得到树高
H≈log2LH \approx \log_{2}{L}H≈log2L
而我们的XXX 的目标树高为
Hx≈log2XH_x \approx \log_{2}{X}Hx≈log2X
每次旋转,X都会减少一层树高(升上去了)
所以我们的旋转次数
Spin=H−Hx≈log2L−log2XSpin=H -H_x \approx \log_{2}{L} - \log_{2}{X}Spin=H−Hx≈log2L−log2X
由于我们的X是在[0,L][ 0,L][0,L] 内等可能的
那么期望旋转次数为加权平均数
∑X=0L1L∗(log2L−log2X)\sum_{X=0}^L \frac{1}{L}*(\log_{2}{L} - \log_{2}{X})X=0∑LL1∗(log2L−log2X)
即
≈1L∫0L(log2L−log2X)dX\approx\frac{1}{L} \int_0^L(\log_{2}{L} - \log_{2}{X}) d{X}≈L1∫0L(log2L−log2X)dX
=1Lln2[XlnL−XlnX+X]0L=\frac{1}{L \ln{2}} [X\ln{L} -X\ln{X} +X]_0^L=Lln21[XlnL−XlnX+X]0L
=1ln2−0=1.44=\frac{1}{\ln{2}}-0=1.44=ln21−0=1.44
证明完毕.