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树的更多相关文章

  1. 浅谈B+树索引的分裂优化(转)

    http://www.tamabc.com/article/85038.html 从MySQL Bug#67718浅谈B+树索引的分裂优化   原文链接:http://hedengcheng.com/ ...

  2. 浅谈oracle树状结构层级查询之start with ....connect by prior、level及order by

    浅谈oracle树状结构层级查询 oracle树状结构查询即层次递归查询,是sql语句经常用到的,在实际开发中组织结构实现及其层次化实现功能也是经常遇到的,虽然我是一个java程序开发者,我一直觉得只 ...

  3. 浅谈oracle树状结构层级查询测试数据

    浅谈oracle树状结构层级查询 oracle树状结构查询即层次递归查询,是sql语句经常用到的,在实际开发中组织结构实现及其层次化实现功能也是经常遇到的,虽然我是一个java程序开发者,我一直觉得只 ...

  4. (转)浅谈trie树

    浅谈Trie树(字典树)         Trie树(字典树) 一.引入 字典是干啥的?查找字的. 字典树自然也是起查找作用的.查找的是啥?单词. 看以下几个题: 1.给出n个单词和m个询问,每次询问 ...

  5. 浅谈Huffman树

    所谓Huffman树,就是叶子结点带权的\(K\)叉树,假设每个叶子的权值为\(v\),到根的距离为\(dep\),那么最小化\(\sum v_i*dep_i\)就是\(Huffman\)树的拿手好戏 ...

  6. 【转】Senior Data Structure · 浅谈线段树(Segment Tree)

    本文章转自洛谷 原作者: _皎月半洒花 一.简介线段树 ps: _此处以询问区间和为例.实际上线段树可以处理很多符合结合律的操作.(比如说加法,a[1]+a[2]+a[3]+a[4]=(a[1]+a[ ...

  7. 浅谈B树

    B树即二叉搜索树: 1.所有非叶子结点至多拥有两个儿子(Left和Right): 2.所有结点存储一个关键字: 3.非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树: 如:    ...

  8. 浅谈 trie树 及其实现

    定义:又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构, 如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树. 核心思想:是空间换时间.利用字符串的公共前缀来降低查询时间的开 ...

  9. 浅谈Trie树(字典树)

          Trie树(字典树) 一.引入 字典是干啥的?查找字的. 字典树自然也是起查找作用的.查找的是啥?单词. 看以下几个题: 1.给出n个单词和m个询问,每次询问一个单词,回答这个单词是否在单 ...

随机推荐

  1. 【java】this用法

    this代表当前类的引用对象:哪个对象调用方法,该方法内部的this就代表那个对象this关键字主要有两三个应用: (1)this调用本类中的属性,也就是类中的成员变量: class People { ...

  2. 不常用的vi命令

    vi u 撤回ctrl+r 撤回的撤回 全文替换%s/old/new/g 指定行区间替换12,15s/old/new/g c替换前确认12,15s/old/new/gc 用#代替分隔符,用户关键字有/ ...

  3. 理解OpenShift(3):网络之 SDN

    理解OpenShift(1):网络之 Router 和 Route 理解OpenShift(2):网络之 DNS(域名服务) 理解OpenShift(3):网络之 SDN 理解OpenShift(4) ...

  4. finstrument-functions

    2017-12-03 23:59:16 参考 如何快速地在每个函数入口处加入相同的语句? https://www.zhihu.com/question/56132218 做个存档 scj@scjCom ...

  5. 廖雪峰Java6 IO编程-2input和output-7序列化

    1.序列化 序列化是指把一个Java对象变成二进制内容byte[] 序列化后可以把byte[]保存到文件中 序列化后可以把byte[]通过网络传输 一个Java对象要能序列化,必须实现Serializ ...

  6. sqlserver 带输出参数的存储过程的创建与执行

    创建 use StudentManager go if exists(select * from sysobjects where name='usp_ScoreQuery4') drop proce ...

  7. javascript常用工具类整理(copy)

    JavaScript常用工具类 类型 日期 数组 字符串 数字 网络请求 节点 存储 其他 1.类型 isString (o) { //是否字符串 return Object.prototype.to ...

  8. RGB ECT 4BIT 压缩后质量远高于RGB ETC2 4BIT

    今天突然发现这个.原来以为ETC2在任何方面都强于ETC,没想到...用了RGB ETC2 4BIT 压缩的贴图看起来有点糊,改用RGB ECT 4BIT后竟然非常清晰,而且大小与RGB ECT2 4 ...

  9. java学习--面向对象

    对象及类的概念 对象是java程序的核心,在java程序中“万事万物皆对象” 对象可以看成是属性和方法的封装体 类是用来创建同一类型的对象的模板,在一个类中定义了该类对象所应具有的属性和方法 J2SD ...

  10. 【原创】python嗅探QQ消息实战

    目录 需求分析 选型 设计与流程 实现过程 结果展示 1 需求分析   在一些业务场景中需要拿到IM上的通信记录来做一些数据分析,例如对QQ平台中的消息进行领域分类等. 2 选型 环境与工具: pyt ...