【算法学习】有旋treap
treap是平衡树的一种。与其他平衡树一样,它也能够支持插入和删除,求第k极值等,接下来我们主要探讨有旋treap的实现过程。
treap中每个节点要维护其值,左右孩子以及子树大小。父亲要不要写则看你的写法了,如果用的是指针或引用传入,则没有必要写。
特别的是,treap的每个节点还需要维护另一个值——它的优先度,优先度在节点新建时就赋值,并且在节点删除前不会改变。
treap的平衡性就取决于这个关键的值,这个值在一开始是随机赋值的,在建立平衡树时,还需要让结点的优先度有堆性质!
即意结点的原值要呈二叉排序树结构,而结点的“优先度”要满足父节点的优先度比两个儿子结点的优先度都要大!
也就是说treap既是一棵二叉排序树,还是一个堆【其实只是有堆性质,并不是严谨的堆的定义】!
这意味着当每个结点的优先度都不同时,这棵树只有一种排列方式满足它既是二叉排序树,也是堆(想一想为什么)。
而这种排列方式平均来说是平衡的,即它的树高正比于logn。这是因为优先度是随机赋值的,随机化思想给了它这个性质。
在修改时,不需要刻意维护平衡,只要当其堆性质被破坏,把它恢复就可以了。
====
接下来看具体实现过程:
我用的是指针+引用写法,目前写了插入,删除和查询某节点的排名。
接下来我们边看代码边分析:
namespace Treap{//我专门搞了个命名空间……
}
struct node{//这里是结点的结构体定义,要注意每个东西都要指针,因为这是指针写法
int val,pri,siz;//值,优先度和子树大小
node* son[];//孩子
node();//构造函数,定义在下面
}*null=new node,*root=new node;//空结点(null)和根结点(root)
node::node(){son[]=son[]=null;}//在结构体外定义构造函数要加"::"
inline ]->siz+x->son[]->siz+;}//这个函数用于更新结点的子树大小
inline void rotate(node* &x,bool lr){//典型的平衡树旋转函数
//传进去的第一个是引用的节点指针,第二个表示左/右旋
//传指针不奇怪,传引用是为什么呢?
//这是因为在旋转时把结点x和它的左/右孩子互换了位置,x原来的父亲现在的孩子指针要修改,可是我们没有父亲指针,所以传引用,在指针x的地址改变时,调用它时的传进去的父亲的孩子指针也会改变。
node *v=x->son[lr^],*vs=v->son[lr];//保存一下中间变量
x->son[lr^]=vs;//往一边旋,x的新“另一边”孩子就是x的原“另一边”孩子的“同一边”孩子
v->son[lr]=x;//而要旋转的另一个结点的孩子改变为x
combine(x);combine(v);//重新计算siz
x=v;//改变x的指针,指向子树的新根,这样可以使原父亲的孩子指针也变化
}
先写到这里……以后再补充
【算法学习】有旋treap的更多相关文章
- 浅谈无旋treap(fhq_treap)
一.简介 无旋Treap(fhq_treap),是一种不用旋转的treap,其代码复杂度不高,应用范围广(能代替普通treap和splay的所有功能),是一种极其强大的平衡树. 无旋Treap是一个叫 ...
- [转载]无旋treap:从单点到区间(例题 BZOJ1500&NOI2005 维护数列 )
转自ZZH大佬,原文:http://www.cnblogs.com/LadyLex/p/7182631.html 1500: [NOI2005]维修数列 Time Limit: 10 Sec Mem ...
- [您有新的未分配科技点] 无旋treap:从单点到区间(例题 BZOJ1500&NOI2005 维护数列 )
1500: [NOI2005]维修数列 Time Limit: 10 Sec Memory Limit: 64 MB Description Input 输入的第1 行包含两个数N 和M(M ≤20 ...
- 【算法学习】Fhq-Treap(无旋Treap)
Treap——大名鼎鼎的随机二叉查找树,以优异的性能和简单的实现在OIer们中广泛流传. 这篇blog介绍一种不需要旋转操作来维护的Treap,即无旋Treap,也称Fhq-Treap. 它的巧妙之处 ...
- [转载]无旋treap:从好奇到入门(例题:bzoj3224 普通平衡树)
转载自ZZH大佬,原文:http://www.cnblogs.com/LadyLex/p/7182491.html 今天我们来学习一种新的数据结构:无旋treap.它和splay一样支持区间操作,和t ...
- [您有新的未分配科技点]无旋treap:从好奇到入门(例题:bzoj3224 普通平衡树)
今天我们来学习一种新的数据结构:无旋treap.它和splay一样支持区间操作,和treap一样简单易懂,同时还支持可持久化. 无旋treap的节点定义和treap一样,都要同时满足树性质和堆性质,我 ...
- [Bzoj3224][Tyvj1728] 普通平衡树(splay/无旋Treap)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3224 平衡树入门题,学习学习. splay(学习yyb巨佬) #include<b ...
- 非旋Treap及其可持久化
平衡树这种东西,我只会splay.splay比较好理解,并且好打,操作方便. 我以前学过SBT,但并不是很理解,所以就忘了怎么打了. 许多用平衡树的问题其实可以用线段树来解决,我们真正打平衡树的时候一 ...
- 「学习笔记」Treap
「学习笔记」Treap 前言 什么是 Treap ? 二叉搜索树 (Binary Search Tree/Binary Sort Tree/BST) 基础定义 查找元素 插入元素 删除元素 查找后继 ...
随机推荐
- YARN结构分析与工作流程
YARN Architecture Link: http://hadoop.apache.org/docs/r2.7.2/hadoop-yarn/hadoop-yarn-site/YARN.html ...
- Leetcode模拟题篇
43. Multiply Strings 高精度非负整数的乘法. string multiply(string num1, string num2) { '); ; <= i; --i) { ; ...
- AGC019
质量果然挺高的. A 贪心. ll Q,H,S,D,N; int main() { cin>>Q>>H>>S>>D>>N; H=min(H, ...
- Integer to Roman - LeetCode
目录 题目链接 注意点 解法 小结 题目链接 Integer to Roman - LeetCode 注意点 考虑输入为0的情况 解法 解法一:从大到小考虑1000,900,500,400,100,9 ...
- CF662C Binary Table 【状压 + FWT】
题目链接 CF662C 题解 行比较少,容易想到将每一列的状态压缩 在行操作固定的情况下,容易发现每一列的操作就是翻转\(0\)和\(1\),要取最小方案,方案唯一 所以我们只需求出每一种操作的答案 ...
- Fowsniff: 1靶机入侵
一.信息收集 1.存活主机扫描 arp-scan -l 发现192.168.1.13是目标靶机的IP地址 2.端口扫描 接下来用nmap神器来扫描目标IP地址,命令如下: root@kali2018 ...
- 关于JavaScript诞生之初的趣事
我在读很多优秀的JavaScript源码时候常常被它诡异的语法搞的精疲力尽,所以时不时的加固JavaScript基础知识是十分有必要的,这些知识每次温故或者你换个角度去思考都能收获颇多,那么如此深不可 ...
- Eureka的一些注意事项
1.心跳设置:只能在application.yml中 2. 注册到Eureka上面的服务名称 与swagger2使用的时候,需要配置此项,否则显示服务名称为unknown 3.高可用的Eureka 4 ...
- 四、Linux学习之文件处理命令
1.建立目录:mkdir 格式:mkdir –p [目录名] -p 递归创建目录 注意事项: 如果是创建单个目录直接mkdir [目录名就可以] 如果是创建一个目录下的目录也就是递归创建目录请 ...
- array_unshift() 函数用于向数组插入新元素。新数组的值将被插入到数组的开头。
<?php $a=array("a"=>"red","b"=>"green"); array_unsh ...