真·浅谈treap树
treap树是一种平衡树,它有平衡树的性质,满足堆的性质,是二叉搜索树,但是我们需要维护他
为什么满足堆的性质?因为每个节点还有一个随机权值,按照随机权值维持这个堆(树),可以用O(logn)的复杂度维护他。树的期望深度是log n。
平衡树是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。权值:右儿子大于爸爸大于左儿子。
那么如何维护他呢?
我们来看看维护treap树的几个操作。
1.左旋右旋:
旋转是什么?看图:

把父亲和他左(右)儿子及其各子树调换(反了!)
左旋:左儿子上窜(爸爸的左儿子换成儿子的右儿子,儿子的右儿子换成爸爸)
右旋:右儿子上窜(爸爸的右儿子换成儿子的左儿子,儿子的左儿子换成爸爸)
左旋右旋看上去没有用,但是他是服务于插入和删除操作的。
代码:
void update(int cur){
sz[cur] = sz[lc[cur]] + sz[rc[cur]] + ;
}
void right_rotate(int &Q){
int P = lc[Q];
lc[Q] = rc[P];
rc[P] = Q; //爸爸的左儿子换成儿子的右儿子,儿子的右儿子换成爸爸
update(Q); //更新右子树大小
update(P); //更新左子树大小
Q = P; //把Q换成P
}
void left_rotate(int &Q){
int P = rc[Q];
rc[Q] = lc[P];
lc[P] = Q;
update(Q);
update(P);
Q = P;
}
2.插入
插入就需要左旋右旋了,因为我们既维持treap其平衡树的性质,也要维持他堆的性质。
void insert(int &cur, int v){
if(!cur)
{
cur = ++cnt; //新加点的编号
V[cnt] = v; //把权值赋给它
R[cnt] = rand(); //给出点的随机权值
return;
}
if(v < V[cur]) //比较新加点与当前点的权值
{
insert(lc[cur], v); //把当前点放到他左儿子身上,递归下去
update(cur); //更新子树大小
if(R[lc[cur]] < R[cur]) //保持堆的性质
right_rotate(cur);
}
else
{
insert(rc[cur], v); //把当前点放到他左儿子身上,递归下去
update(cur); //更新子树大小
if(R[rc[cur]] < R[cur]) //保持堆的性质
left_rotate(cur);
}
}
3.删除
void del(int &cur, int v){//cur当前节点,v表示要删的点的权值
if(!cur)
return;
if(V[cur] == v)
{
if(lc[cur] && rc[cur])
{
left_rotate(cur);
del(lc[cur], v);
}
else
{
cur = lc[cur] | rc[cur];
update(cur);
return;
}
}
else if(V[cur] > v)
del(lc[cur], v);
else
del(rc[cur], v);
update(cur);
}
4.第k大,前驱,后继
这些都是递归求的。
比如前驱,如果当前点的权值小于要找的值,那么走它的右子树,直到当前点权值大于要找的值,找它的左子树,因为左子树比当前点权值小。
int find(int cur, int v)
{
if(V[cur] == v)
return ;
else if(V[cur] > v)
return find(lc[cur], v);
else
return sz[lc[cur]] + + find(rc[cur], v);
}
int pre(int cur,int v)
{
if(!cur)
return 0xefefefef;
if(v < V[cur])
return pre(lc[cur],v);
return max(V[cur],pre(rc[cur],v)); }
int post(int cur,int v)
{
if(!cur)
return 0x7fffffff;
if(v > V[cur])
return post(rc[cur],v);
return min(V[cur],post(lc[cur],v));
}
差不多就是这些……
洛谷板题:https://www.luogu.org/problemnew/show/P3369
真·浅谈treap树的更多相关文章
- 浅谈B+树索引的分裂优化(转)
http://www.tamabc.com/article/85038.html 从MySQL Bug#67718浅谈B+树索引的分裂优化 原文链接:http://hedengcheng.com/ ...
- 浅谈oracle树状结构层级查询之start with ....connect by prior、level及order by
浅谈oracle树状结构层级查询 oracle树状结构查询即层次递归查询,是sql语句经常用到的,在实际开发中组织结构实现及其层次化实现功能也是经常遇到的,虽然我是一个java程序开发者,我一直觉得只 ...
- 浅谈oracle树状结构层级查询测试数据
浅谈oracle树状结构层级查询 oracle树状结构查询即层次递归查询,是sql语句经常用到的,在实际开发中组织结构实现及其层次化实现功能也是经常遇到的,虽然我是一个java程序开发者,我一直觉得只 ...
- (转)浅谈trie树
浅谈Trie树(字典树) Trie树(字典树) 一.引入 字典是干啥的?查找字的. 字典树自然也是起查找作用的.查找的是啥?单词. 看以下几个题: 1.给出n个单词和m个询问,每次询问 ...
- 浅谈Huffman树
所谓Huffman树,就是叶子结点带权的\(K\)叉树,假设每个叶子的权值为\(v\),到根的距离为\(dep\),那么最小化\(\sum v_i*dep_i\)就是\(Huffman\)树的拿手好戏 ...
- 【转】Senior Data Structure · 浅谈线段树(Segment Tree)
本文章转自洛谷 原作者: _皎月半洒花 一.简介线段树 ps: _此处以询问区间和为例.实际上线段树可以处理很多符合结合律的操作.(比如说加法,a[1]+a[2]+a[3]+a[4]=(a[1]+a[ ...
- 浅谈B树
B树即二叉搜索树: 1.所有非叶子结点至多拥有两个儿子(Left和Right): 2.所有结点存储一个关键字: 3.非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树: 如: ...
- 浅谈 trie树 及其实现
定义:又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构, 如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树. 核心思想:是空间换时间.利用字符串的公共前缀来降低查询时间的开 ...
- 浅谈Trie树(字典树)
Trie树(字典树) 一.引入 字典是干啥的?查找字的. 字典树自然也是起查找作用的.查找的是啥?单词. 看以下几个题: 1.给出n个单词和m个询问,每次询问一个单词,回答这个单词是否在单 ...
随机推荐
- 【java】this用法
this代表当前类的引用对象:哪个对象调用方法,该方法内部的this就代表那个对象this关键字主要有两三个应用: (1)this调用本类中的属性,也就是类中的成员变量: class People { ...
- 不常用的vi命令
vi u 撤回ctrl+r 撤回的撤回 全文替换%s/old/new/g 指定行区间替换12,15s/old/new/g c替换前确认12,15s/old/new/gc 用#代替分隔符,用户关键字有/ ...
- 理解OpenShift(3):网络之 SDN
理解OpenShift(1):网络之 Router 和 Route 理解OpenShift(2):网络之 DNS(域名服务) 理解OpenShift(3):网络之 SDN 理解OpenShift(4) ...
- finstrument-functions
2017-12-03 23:59:16 参考 如何快速地在每个函数入口处加入相同的语句? https://www.zhihu.com/question/56132218 做个存档 scj@scjCom ...
- 廖雪峰Java6 IO编程-2input和output-7序列化
1.序列化 序列化是指把一个Java对象变成二进制内容byte[] 序列化后可以把byte[]保存到文件中 序列化后可以把byte[]通过网络传输 一个Java对象要能序列化,必须实现Serializ ...
- sqlserver 带输出参数的存储过程的创建与执行
创建 use StudentManager go if exists(select * from sysobjects where name='usp_ScoreQuery4') drop proce ...
- javascript常用工具类整理(copy)
JavaScript常用工具类 类型 日期 数组 字符串 数字 网络请求 节点 存储 其他 1.类型 isString (o) { //是否字符串 return Object.prototype.to ...
- RGB ECT 4BIT 压缩后质量远高于RGB ETC2 4BIT
今天突然发现这个.原来以为ETC2在任何方面都强于ETC,没想到...用了RGB ETC2 4BIT 压缩的贴图看起来有点糊,改用RGB ECT 4BIT后竟然非常清晰,而且大小与RGB ECT2 4 ...
- java学习--面向对象
对象及类的概念 对象是java程序的核心,在java程序中“万事万物皆对象” 对象可以看成是属性和方法的封装体 类是用来创建同一类型的对象的模板,在一个类中定义了该类对象所应具有的属性和方法 J2SD ...
- 【原创】python嗅探QQ消息实战
目录 需求分析 选型 设计与流程 实现过程 结果展示 1 需求分析 在一些业务场景中需要拿到IM上的通信记录来做一些数据分析,例如对QQ平台中的消息进行领域分类等. 2 选型 环境与工具: pyt ...