寒假Day39:Treap平衡树
fhq平衡树
优点:码量小、好写、核心操作的代码都是复读机、支持的操作多
缺点:常数略大
可以解决LCT问题
普通Treap用来维护树的平衡的操作:树旋转
fhq平衡树的操作:分裂split和合并merge 把树反复拆开再拼上
treap=tree+heap
性质:平衡树上的每一个结点存放两个信息:一个是值(满足二叉树的性质),一个是随机的索引(满足堆的性质),结合二叉搜索树和二叉堆的性质来使树平衡。
对于随机数据来说,很多朴素算法跑的比正解快,但是一些毒瘤数据会卡朴素算法的最坏时间复杂度,结果会TLE
二叉搜索树BST的性质:
左结点比当前结点小,右节点比当前结点大
二叉堆(大根堆)的性质:
(想用堆用的都是优先队列)是一个完全二叉树
父节点的优先级总是大于或等于任何一个子节点的优先级
每个节点都有val值,根节点的val值大于左右节点
不用二叉搜索树的原因?
因为可能插入的数据是一组有序数组,那么就都在根节点的一侧,会退化成链,不利于搜索,所以需要进行旋转
结点存储的信息:左右节点、结点值key、val存储随机值、cnt这个节点有几个,size以此为根节点的有多少
插入操作:
正常插入
删除操作:
如果这个节点的值得个数大于1,就直接减一;否则进行旋转(需要把该结点旋转到叶结点再删除)。
旋转:需要判断多种情况
如果该节点没有儿子,则直接删除
右旋的情况:该节点没有右儿子;该节点的左儿子的值大于右儿子
除此之外:左旋
查找操作:
根据值查找排名;
根据排名找值;
寻找前驱;比他小的最大值
寻找后继。比他大的最小值
Treap为什么会平衡?