普通平衡树(treap)

本文介绍了Treap数据结构,它是基于二叉查找树(BST)的优化,通过引入随机权值实现平衡。文章详细阐述了Treap的插入、删除、查询排名、查询数值、求前驱和后继等操作,并解释了旋转在保持平衡中的作用。通过随机权值,Treap可以在平均情况下保持良好的性能,所有操作的时间复杂度为O(logn)。
摘要由CSDN通过智能技术生成

前言

您需要写一种数据结构,来维护一些数,其中需要提供一下的操作:
1.插入数值x
2.删除数值x(如果有多个,只删除一个)
3.查询数值x的排名(如有多个相同的数,应输出最小的排名)
4.查询排名为x的数值
5. 求数值x的前驱(小于x最大的数)
6.求数值x的后继(大于x最小的数)

首先我们引入一种数据结构叫二叉查找树(BST)。该树满足一下性质:
对于树的任意一个节点
1.该节点的关键码不小于它的左子树中任意节点的关键码
2.该节点的关键码不大于它的右子树中任意节点的关键码

通俗一点来讲就是,一个节点的左边都比他小,右边都比他大QWQ

显然,二叉查找树的中序遍历是一个单调递增的节点序列……

那么我们来考虑解决上面的普通平衡树(因为不是主角就不重点讲啦!!)

1.插入:从根节点开始访问,小了向左走,大了向右走,找不到就新建点啦
2.删除:同插入过程啦啦啦啦
3.查询排名:因为左子树的点都比此节点小,那抹排名就是左子树的size(大小)+1啦啦啦,求size应该都会吧……
4.查询数值:如果左子树的大小比要求排名大,就往左走,否则往右走,直到一样……
5.前驱:首先我们先找到这个数,因为左子树的点都比这个数小,所以向左儿子走一步,然后一直向右边走,走到头就是啦
6.后继:同理啦,向右儿子走一步,然后一直向左走

是不是感觉BST超简单的,没错就是这么简单……但是你没发现什么问题嘛??
这里写图片描述

不不不这里写图片描述

现在我按顺序插入1,2,3,4,5
树就变成了这样
我要是按顺序插入1,2,3……10^5
这特么不就变成链表了么这里写图片描述
实际上就算不这么极端,也能分分钟把这种最单纯的2x查找树搞死
这里写图片描述
很显然这样是过不了普通平衡树的……

是不是感觉刚才看的都白看了,不不不,下面要将的treap就是基于2x进行优化的……

那么该怎么优化呢???

我们发现2x查找树的不足之处就在于它太深了(太深了……咳咳咳),因此我们就想减少它的深度,通俗的来讲就是把它拍扁。那么如何实现呢……

旋转(不转不是中国人……)
右旋,是让某个节点的左儿子站到自己原来的位置,然后自己成为原来左儿子的右儿子(左旋同理啦!!请自行脑补)可以看下面的动来动去的图
这里写图片描述

合理的旋转操作可以是BST变得更扁(you)平(xiu)。那么问题来了,怎么样才算合理呢???根据研究发现,在随机的数据下,普通的BST可以虐杀其他一切高级的树。Treap的思想就是利用“随机”来创造平衡的条件。因为在旋转的过程中必须维持BST的性质,所以Treap就把“随机”作用在堆性质上。
其实Treap就是Tree和Heap的合成词啦。Treap在插入每个新节点的时候,就给该节点随机生成一个额外的权值。然后像二叉堆的插入过程一样,自底向上依次检查,当某个节点不满足大根堆性质

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值