关于Treap的学习感受

                                                                       

好了我就很愉快的回来补坑了~

Treap也是一种平衡树,它较普通二叉查找树而言,每个节点被赋予了一个新的属性:优先级(没错就是类似优先队列的优先),对于Treap中的每个结点,除了它的权值满足二叉查找树的性质外,它的优先级还满足堆性质,也就是结点的优先级小于它所有孩子的优先级。

换句话说,从权值上看,Treap是一个二叉查找树;从优先级上看,Treap是一个堆。所以我们发现Treap其实可以看做是Tree+Heap。

我们发现普通BST会不平衡是因为有序的数据会使查找路径退化成链,而随机数据使其退化的概率非常小。因此我们在Treap中赋予的这个优先级的值采用随机生成的办法,这样Treap的结构就趋于平衡了。(如果脸黑怎么办(逃))

如果我们假设所有点的权值与优先级都互不相同,那么Treap的形态是唯一确定的。

我们考虑在所有结点中找到优先级最小的点,则它一定是Treap的根,而权值小于它的点会在根的左子树,大于它的点会在根的右子树,这就可以递归下去构建Treap。这个建立过程与快速排序类似,因此Treap的期望深度与快排的期望递归层数一样都是O(log n)的。

为了使Treap满足性质,有时我们不可避免地要对结构进行调整,而我们调整的方式是旋转。在维护Treap的过程中,我们会出现两种旋转:左旋与右旋。

左旋一个子树,这个子树的根节点为x,则旋转后会把x变为这个子树的新根的左儿子,x的右儿子会成为子树新的根。右旋一个子树,这个子树的根节点为x,则旋转后会把x变为这个子树的新根的右儿子,x的右儿子会成为子树新的根。(详细图解见Splay,传送门:https://blog.csdn.net/g21glf/article/details/82931486)。

显然旋转后这个Treap仍然满足权值的BST性质,因此这个旋转操作就保证了,若我们满足了BST性质,那么不满足堆性质的部分我们可以通过旋转,使其满足堆性质。旋转的意义也正是在此,使不满足堆序的两个节点通过调整位置,重新满足堆序,而不改变BST性质。

Treap的各种操作与BST无异,唯一有些不同的就是插入操作。我们从根节点开始插入,如果要插入的值小于当前节点的值,那么我们要在当前节点的左子树进行插入;否则我们要在当前节点的右子树进行插入; 若当前节点是个空节点, 则我们在这个位置上新建一个节点。插入之后新建的这个节点可能会使Treap不满足堆性质,那么我们就通过旋转操作不断调整,这个步骤可以通过递归来实现。

在删除时,我们首先需要在Treap上走,找到需要删除的那个节点,接着我们可以利用旋转操作不停调整需要删除的这个节点在树中的位置。若删除节点为叶节点,那么我们可以直接删除; 若它只有一个儿子, 那么我们直接让那个儿子代替这个被删除的节点即可。 否则,若删除节点左儿子的优先级小于删除节点右儿子优先级,那么我们对删除节点进行右旋,让左儿子成为新的子树的根;反之同理。直到它变为前两种情况。

由于Treap的树高是期望O(log n)的,所以它各个操作的期望复杂度也是O(log n)。

【贴代码~】

更新
void update(const int &k)
{tr[k].size=tr[lc[k]].size+tr[rc[k]].size;
}
右旋
void zig(int &k)
{int y=lc[k];lc[k]=rc[y];rc[y]=k;size[y]=size[k];update(k);k=y;
}
左旋
void zag(int &k)
{int y=rc[k];rc[k]=lc[y];lc[y]=k;size[y]=size[k];update(k);k=y;
}
插入
void insert(int &k,int &key)
{if(!k){k=++pool;key[k]=key;pri[k]=rand();cnt[k]=size[k]=1;lc[k]=rc[k]=0;return ;}else++size[k];if(k.key==key)++cnt[k];else{if(key<k.key){insert(lc[k],key);if(pri[lc[k]]>pri[k])zig(k);}else{insert(rc[k],key);if(pri[rc[k]]<pri[k])zag(k);}}return ;
}
删除
void del(int &k,int &key)
{if(k.key==key){if(cnt[k]>1)cnt[k]--,size[k]--;else{if(!lc[k]||!rc[k])k=lc[k]+rc[k];else{if(pri[lc[k]]<pri[rc[k]])zig(k),del(k,key);elsezag(k),del(k,key);}}}else--size[k];if(key<k.key)del(lc[k],key);elsedel(rc[k],key);return ;	
}
询问优先级
int queryrank(const int &key)
{int x=rt,res=0;while(x){if(key==key[x])return res+size[lc[x]]+1;if(key<key[x])x=lc[x];elseres+=size[lc[x]]+cnt[x],x=rc[x];}return res;
}
寻找第k大
int querykth(int k)
{int x=rt;while(x){if(size[lc[x]]<k&&size[lc[x]]+size[x]>=k)return x.key;if(size[lc[x]]>=k)x=lc[x];elsek-=size[lc[x]]+cnt[x],x=rc[x];}return 0;
}
求前驱
int querypre(const int &k)
{int x=rt,res=-INF;while(x){if(key[x]<key)res=key[x],x=rc[x];elsex=lc[x];}return res;
}
求后继
int querysuf(const int &k)
{int x=rt,res=INF;while(x){if(key[x]>key)res=key[x],x=lc[x];elsex=rc[x];}return res;
}

以上就是个人关于Treap的一些感悟,后续会补坑。。。

转载于:https://www.cnblogs.com/Ishtar/p/10010833.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/464793.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2022年考研结束了

为期两天的研究生考试结束了。我没参加研究生考试&#xff0c;所以对研究生考试的压力不从得知&#xff0c;我从一个外人的角度来看&#xff0c;这无非就是一个简单的考试&#xff0c;考上了欢喜雀跃&#xff0c;考不上嘛&#xff0c;我就会说&#xff0c;大不了来年再考一次&a…

挂“洋头”卖奶粉,澳优还要欺骗好久

澳优奶粉近期被质疑非进口产品&#xff0c;公司总部实为湖南一家贴牌商。该奶粉生产商澳优乳业公司回应称其为“国外产品与本国品牌相结合”的国际化企业。但奶粉包装仍被质疑误导消费者&#xff0c;且售价偏高&#xff0c;澳优方称“与其高端品质相比只属于中上水平”&#xf…

mysql通过局域网访问数据库_MySQL数据库之局域网内访问同一个mysql数据库

本文主要向大家介绍了MySQL数据库之局域网内访问同一个mysql数据库 &#xff0c;通过具体的内容向大家展现&#xff0c;希望对大家学习MySQL数据库有所帮助。局域网内访问同一个mysql数据库。一、运行cmd&#xff0c;输入mysql -u root -p。二、输入mysql数据库密码&#xff0c…

约翰·冯·诺依曼:一个向上帝买了挂的男人!!

来源|David 小咸鱼/新智元约翰冯诺依曼是20世纪最有影响力的人物之一。从原子弹&#xff0c;到计算机、再到量子力学、气候变化&#xff0c;你可能很难再找出像这样对我们今天的世界和生活影响更大的科学家了。在20世纪的天才中&#xff0c;有几个杰出的人物&#xff1a;爱因斯…

POJ 2976 Dropping Tests

http://poj.org/problem?id2976 题目大意&#xff1a;给定n个二元组(a,b)&#xff0c;扔掉k个二元组&#xff0c;使得剩下的 最大。 这两天一直在搞分数规划&#xff0c;有了前两道题&#xff08;3621、2728&#xff09;&#xff0c;这道题就是完完全全的大水题了。 设 r100…

回调函数这个是什么鬼?

这是一个同学在微信给我提问的问题。要搞清楚回调函数&#xff0c;我们首先要搞清楚函数&#xff0c;函数其实就是一个地址&#xff0c;这个地址描述了这个函数在内存中的位置。但是函数和变量也是一样的&#xff0c;有类型&#xff0c;对变量来说&#xff0c;变量会分成各种类…

小米12比我的小米10还便宜

昨天晚上&#xff0c;小米发布会发布了新的小米12手机&#xff0c;价格很亲民&#xff0c;比我两年前买的小米10还便宜。这还不算&#xff0c;小米12比小米10还更好看。小米在尝试曲面屏之后&#xff0c;终于觉得曲面屏不再是一个可以用来炫耀的卖点了。我自己的小米10曲面屏&a…

庆祝51CTO六周年:资源牛人有奖比拼,生日当天疯狂送豆!(已结束)

2011年8月15日&#xff0c;是51CTO成立6周年的日子。为庆祝这一盛典&#xff0c;特推出此活动。一、活动时间&#xff1a;2011年8月5日——2011年8月25日 24:00二、活动奖项及规则&#xff1a;1、资源牛人金奖&#xff1a;入围资源牛人排行榜前十名的Down友已经产生&#xff0c…

mysql3.5 所有表_mysql学习笔记3.5

紧接着笔记3的训练介绍一个对于我来说的比较难的难点&#xff01;&#xff01;&#xff01;&#xff01;select * from sc;select student.sno,sname,avg(grade) as平均分fromstudent,scwhere student.snosc.snogroup bystudent.snohaving avg(grade)>90/*这一个条件我竟然忘…

CPU上电后加载程序的流程 | 基于RK3399

芯片上电解复位之后执行的第一段程序&#xff0c;在芯片中称之为Bootrom loader。这部分程序在芯片制造过程中固化到其内部的ROM空间&#xff0c;具备只读属性&#xff0c;在实际使用过程中无法修改这部分内容&#xff0c;这部分程序的知识产权也仅归属于芯片公司所有。其实&am…

IPv6与IPv4的区别

Technorati 标签: Hank--network porter■第一个就不说哈&#xff0c;32bit直接升级到128bit了。 从2的32次方升级到2的128次方了&#xff0c;地球上的每一粒沙子都可以分到一个IP地址。这个是IPv6最拉风的地方. ■在IPv6中&#xff0c;路由器不能用自动配置机制来配置接口&…

在腾讯的这半年

晚上和同事聚餐后&#xff0c;我和李总坐车回公司&#xff0c;李总在电话里面和大家开会&#xff0c;然后说着各种让大家帮忙的话&#xff0c;我看着窗外密密麻麻的车辆——想着&#xff0c;这一年又要过去了。我是有总结的习惯的&#xff0c;不管是做事情还是生活&#xff0c;…

mysql数据删除后无法恢复数据恢复_Mysql数据库delete删除后数据恢复报告

原标题&#xff1a;Mysql数据库delete删除后数据恢复报告数据库环境部署与故障原因&#xff1a;本次恢复的数据库安装在客户本地服务器上&#xff0c;服务器操作系统为windows2008 r2 。在当前环境内安装有mysql5.6单实例&#xff0c;引擎类型为innodb&#xff0c;表内数据存储…

Linux启动流程 | kernel执行第一个init应用程序的实现原理

1. 概述Linux系统启动过程中通过init_task创建0号idle进程。然后通过kernel_thread创建1号init进程。创建该进程时通过系统调用&#xff0c;在内核空间执行用户空间的/sbin/init程序&#xff0c;通过该程序产生出shell&#xff0c;并依赖init衍生出其他进程。通过top命令查看当…

poj1484

简单题 View Code #include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>using namespace std;#define maxn 25int n, m, blow, power[maxn];bool on[maxn];void out(int a){int b m - a - 1;int x;for (int i 0; i < b; i…

西安下雪了,做了一个室内温度计

摘要&#xff1a;最近各地都在下雪&#xff0c;湖南湖北西安都下雪了。养热带花草和宠物的同学们需要多留意室内温度。下面教一个实用性强、制作简单的温度计。使用DS18B20温度传感器和OLED模块构建&#xff0c;这里使用的开发板是Arduino。本项目的源码和3D文件在后台回复&…

oci mysql_Oracle常用的OCI函数

欢迎进入Oracle社区论坛&#xff0c;与200万技术人员互动交流 >>进入 sword OCIEnvInit ( OCIEnv **envhpp, ub4 mode, size_t xtramemsz, dvoid **usrmempp ); 注&#xff1a; 在8i以后&#xff0c;可用OCIEnvCreate一个函数就可以初始化环境了&#xff0c;相当于OCIIni…

android mysql 图片_android sqlite添加图片到数据库

sqlite图片是怎么储存的呢&#xff1f;其实是二进制的方式存储的blob代表使用二进制储存 (更多类型参考&#xff1a;数据库简介)在创建表的地方,VALUE_PIC代表存储图片字段&#xff0c;blob代表这个字段是以二进制储存的。/*创建表语句 语句对大小写不敏感 create table 表名(字…

MCU为什么内部不集成晶振

01MCU为什么不集成晶振本文将用STM32代替MCU。原因1&#xff1a;早些年&#xff0c;芯片的生产制作工艺也许还不能够将晶振做进芯片内部&#xff0c;但是现在可以了。这个问题主要还是实用性和成本决定的。实用性&#xff1a;如果封装进入STM32内部&#xff0c;不利于不同客户更…