Treap
Posted lh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Treap相关的知识,希望对你有一定的参考价值。
先推荐一篇文章和黄学长的代码http://hzwer.com/1712.html https://wenku.baidu.com/view/c8c11e1e650e52ea55189887.html
Treap,顾名思义,Tree+Heap,它既满足二叉搜索树的性质,又满足堆的性质
对于二叉搜索树,如果我们把数有序加入,那么它的时间效率会退化成O(n)。
我们引入一个随机数(即下文描述的修正值),使得随机数满足堆的性质(小根堆或大根堆,不一定要是完全二叉树),这样就能有效避免退化的情况
Treap可以定义为有以下性质的二叉树:
1.若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值,而且它的根节点的修正值小于等于左子树根节点的修正值;
2.若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值,而且它的根节点的修正值小于等于右子树根节点的修正值;
3.它的左、右子树也分别为Treap。
如何构建treap?
一:旋转
为了维护它的堆性质和二叉搜索树性质,我们引入了一个旋转的概念
左旋:把旋转节点原先父亲的位置用旋转节点代替。把它原先父亲自身和左子树作为它的左子树。把它的左子树作为它原先父亲的右子树
右旋:把旋转节点原先父亲的位置用旋转节点代替。把它原先父亲自身和右子树作为它的右子树。把它的右子树作为它原先父亲的左子树
(左侧图是左旋,右侧图是右旋)
旋转的意义在于:旋转可以使不满足堆序的两个节点通过调整位置,重新满足堆序,而不改变BST性质。
我感觉旋转最麻烦的地方是怎么找到上图中红圈点的父亲的编号(因为没记每个点的父亲,记录的话旋转很麻烦)
通过回溯时传回一个变量来更新它的左(右)孩子(即传回红圈点)
二.查找,遍历方式见二叉搜索树
三.插入
1.从根节点开始插入;
2.如果要插入的值小于当前节点的值,在当前节点的左子树中插入,插入后如果左子节点的修正值小于当前节点的修正值,对当前节点进行右旋;
2.如果要插入的值等于当前节点的值,把当前节点的出现次数+1 (开一个变量记录出现次数);
3.如果要插入的值大于当前节点的值,在当前节点的右子树中插入,插入后如果右子节点的修正值小于当前节点的修正值,对当前节点进行左旋;
4.如果当前节点为空节点,在此建立新的节点,该节点的值为要插入的值,左右子树为空,插入成功。
旋转可以在建好新节点,回溯的时候进行(具体参见代码)
四.删除
情况一,该节点为叶节点或链节点,则该节点是可以直接删除的节点。若该节点有非空子节点,用非空子节点代替该节点的,否则用空节点代替该节点,然后删除该节点。
情况二 ,该节点有两个非空子节点。我们的策略是通过旋转,使该节点变为可以直接删除的 节点。如果该节点的左子节点的修正值小于右子节点的修正值,右旋该节点,
使该节点降为右子树的根节点,然后访问右子树的根节点,继续讨论;反之,左旋该节点,使该节点降为左子树的根节点,然后访问左子树的根节点,继续讨论,直到变成可以直接删除的节点。
这样,Treap的基本操作就讲完了。
Treap功能:
一:查最值
查找一个子树的最小值,从子树的根开始访问,如果当前节点左子节点非空,访问当前节点的左子节点;如果当前节点左子节点已经为空,那么当前节点的值就是这个子树的最小值。查最大值同理
二:求前驱后继
每个地方关于前驱后继的定义可能会有所不同(其实就有没有取等)
求一个元素在平衡树(或子树)中的前驱,定义为查找该元素在平衡树中不大于该元素的最大元素。
相似的,求一个元素在平衡树(或子树)中的后继,定义为查找该元素在平衡树中不小于该元素的最小元素。
求前驱:
1.从根节点开始访问,初始化最优节点为空节点;
2.如果当前节点的值不大于要求前驱的元素的值,更新最优节点为当前节点,访问当前节点的右子节点;
3.如果当前节点的值大于要求前驱的元素的值,访问当前节点的左子节点;
4.如果当前节点是空节点,查找结束,最优节点就是要求的前驱。
求后继同理
三:查询第k大的元素(第k小同理)
如果我们想查找第k小的元素或者询问某个元素在Treap中从小到大的排名时,我们就必须知道每个子树中节点的个数。我们称以一个子树的所有节点的权值之和,为子树的大小。由于插入、删除、旋转等操作,会使每个子树的大小改变,所以我们必须对子树的大小进行动态的维护。
对于旋转,我们要在旋转后对子节点和根节点分别重新计算其子树的大小。
对于插入,新建立的节点的子树大小为1。在寻找插入的位置时,每经过一个节点,都要先使以它为根的子树的大小增加1,再递归进入子树查找。
对于删除,在寻找待删除节点,递归返回时要把所有的经过的节点的子树的大小减少1。要注意的是,删除之前一定要保证待删除节点存在于Treap中。
四:查询k是第几大
以上是关于Treap的主要内容,如果未能解决你的问题,请参考以下文章