Treap

数据结构-Treap(树堆) 详解 Treap(树堆)是一种弱平衡的搜索树,与平衡树相同,Treap就是由Tree和Heap(树和堆)两种数据结构组合而成的数据结构。 Treap的每个节点上要额外储存一个值prioritypriority,代表每个节点的优先级。因此对于每个节点,不仅要满足二叉搜索树的基本性质,还需额外满足父节点的prioritypriority大于两个子节点的prioritypriority。实际上,这个prioriotypriorioty值又被称为"修正值"。 阅读详情

Treap

         Treap=Tree+Heap,Treap是一个二叉搜索树,它的左右子树都分别是一个Treap,和一般二叉排序树不同的是,Treap记录一个额外的数据(v),就是优先级(rank)。Treap在以关键字构成二叉排序树的同时,还满足堆的性质,不过Treap不一定是完全二叉树,而堆必须是完全二叉树.

 

1.结构体定义:

struct data{

         int l,r;  //左右子树

int v;  //当前节点的值

int size; //由该节点为根构成的子树的大小

int rnd; //当前节点的优先级

int w; //和当前节点值相同的个数

}tr[MAXN];

 

2.Treap的性质:

(1)    如果b是a的左子树,那么tree[a].v>tree[b].v;

(2)    如果c是a的右子树,那么tree[a].v<tree[c].v;

(3)    如果b,c分别是a的左右子树,那么tree[a].rank<tree[b].rank&& tree[a].rank<tree[c].rank;

 

3.Treap的旋转:跟普通的旋转一样

代码实现:

void update(int k)//更新结点信息

{

         tr[k].size=tr[tr[k].l].size+tr[tr[k].r].size+tr[k].w;

}

void rturn(int &k)

{

         int t=tr[k].l;tr[k].l=tr[t].r;tr[t].r=k;

         tr[t].size=tr[k].size;update(k);k=t;

}

void lturn(int &k)

{

         int t=tr[k].r;tr[k].r=tr[t].l;tr[t].l=k;

         tr[t].size=tr[k].size;update(k);k=t;

}

 

4.Treap的插入:

(1)按照二叉树的插入方法,将结点插入到树中

(2)根据堆的性质(我们这里为最小堆)和优先级的大小调整结点位置。

代码实现:

void insert(int &k,int x){

         if(k==0){

                   size++;k=size;

                   tr[k].size=tr[k].w=1;tr[k].v=x;tr[k].rnd=rand();

                   return;

         }

         tr[k].size++;

    if(tr[k].v==x)tr[k].w++;

         else if(x>tr[k].v){

                   insert(tr[k].r,x);

                   if(tr[tr[k].r].rnd<tr[k].rnd)lturn(k); //维护堆性质

         }

         else {

                   insert(tr[k].l,x);

                   if(tr[tr[k].l].rnd<tr[k].rnd)rturn(k);

         }

}

 

5.Treap的删除:

(1)利用二叉树的性质,找到和x值相同的节点

(2)如果和x值相同的节点的个数有多个,那么只需要将size和w减一即可

(3)如果和x值相同的节点的个数只有一个,而且其存在一个子结点,那么当前需要删除的结点的值应该更新为存在的子节点的值,如果存在两个子结点,那么判断两个子结点的优先级,优先级值小的被更新为删除结点的值。

代码实现:

void del(int &k,int x){

    if(k==0)return;

         if(tr[k].v==x){

                   if(tr[k].w>1){

                            tr[k].w--;tr[k].size--;return;//若不止相同值的个数有多个,删去一个

                   }

                   if(tr[k].l*tr[k].r==0)k=tr[k].l+tr[k].r;//有一个儿子为空

                   else if(tr[tr[k].l].rnd<tr[tr[k].r].rnd)

                            rturn(k),del(k,x);

                   else lturn(k),del(k,x);

         }

         else if(x>tr[k].v)

                   tr[k].size--,del(tr[k].r,x);

         else tr[k].size--,del(tr[k].l,x);

}

 

6.Treap的应用:

(1) 查询x数的排名(若有多个相同的数,因输出最小的排名)

代码实现:

int query_rank(int k,int x){

    if(k==0)return 0;

         if(tr[k].v==x)return tr[tr[k].l].size+1;

         else if(x>tr[k].v)

                   return tr[tr[k].l].size+tr[k].w+query_rank(tr[k].r,x);

         else return query_rank(tr[k].l,x);

}

(2) 查询排名为x的数

代码实现:

int query_num(int k,int x){

    if(k==0)return 0;

         if(x<=tr[tr[k].l].size)

                   return query_num(tr[k].l,x);

    else if(x>tr[tr[k].l].size+tr[k].w)

                   return query_num(tr[k].r,x-tr[tr[k].l].size-tr[k].w);

    else return tr[k].v;

}

(4)    求x的前驱(前驱定义为小于x,且最大的数)和求x的后继(后继定义为大于x,且最小的数)

代码实现:

int ans=0;

void query_pro(int k,int x){  //前驱

    if(k==0)return;

    if(tr[k].v<x){

                   ans=k;query_pro(tr[k].r,x);

         }

    else query_pro(tr[k].l,x);

}

cout<<tree[ans].v<<endl;

void query_sub(int k,int x){  //后继

         if(k==0)return;

         if(tr[k].v>x){

                   ans=k;query_sub(tr[k].l,x);

         }

         else query_sub(tr[k].r,x);

}

cout<<tree[ans].v<<endl;

 

7.完整代码:

struct data{

         int l,r,v,size,rnd,w;

}tr[MAXN];

int n,size,root,ans;

void update(int k)//更新结点信息

{

         tr[k].size=tr[tr[k].l].size+tr[tr[k].r].size+tr[k].w;

}

void rturn(int &k)

{

         int t=tr[k].l;tr[k].l=tr[t].r;tr[t].r=k;

         tr[t].size=tr[k].size;update(k);k=t;

}

void lturn(int &k)

{

         int t=tr[k].r;tr[k].r=tr[t].l;tr[t].l=k;

         tr[t].size=tr[k].size;update(k);k=t;

}

void insert(int &k,int x)

{

         if(k==0)

         {

                   size++;k=size;

                   tr[k].size=tr[k].w=1;tr[k].v=x;tr[k].rnd=rand();

                   return;

         }

         tr[k].size++;

    if(tr[k].v==x)tr[k].w++;//每个结点顺便记录下与该节点相同值的数的个数

         else if(x>tr[k].v)

         {

                   insert(tr[k].r,x);

                   if(tr[tr[k].r].rnd<tr[k].rnd)lturn(k);//维护堆性质

         }

         else

         {

                   insert(tr[k].l,x);

                   if(tr[tr[k].l].rnd<tr[k].rnd)rturn(k);

         }

}

void del(int &k,int x)

{

    if(k==0)return;

         if(tr[k].v==x)

         {

                   if(tr[k].w>1)

                   {

                            tr[k].w--;tr[k].size--;return;//若不止相同值的个数有多个,删去一个

                   }

                   if(tr[k].l*tr[k].r==0)k=tr[k].l+tr[k].r;//有一个儿子为空

                   else if(tr[tr[k].l].rnd<tr[tr[k].r].rnd)

                            rturn(k),del(k,x);

                   else lturn(k),del(k,x);

         }

         else if(x>tr[k].v)

                   tr[k].size--,del(tr[k].r,x);

         else tr[k].size--,del(tr[k].l,x);

}

int query_rank(int k,int x)

{

    if(k==0)return 0;

         if(tr[k].v==x)return tr[tr[k].l].size+1;

         else if(x>tr[k].v)

                   return tr[tr[k].l].size+tr[k].w+query_rank(tr[k].r,x);

         else return query_rank(tr[k].l,x);

}

int query_num(int k,int x)

{

    if(k==0)return 0;

         if(x<=tr[tr[k].l].size)

                   return query_num(tr[k].l,x);

    else if(x>tr[tr[k].l].size+tr[k].w)

                   return query_num(tr[k].r,x-tr[tr[k].l].size-tr[k].w);

    else return tr[k].v;

}

void query_pro(int k,int x)

{

    if(k==0)return;

    if(tr[k].v<x)

         {

                   ans=k;query_pro(tr[k].r,x);

         }

    else query_pro(tr[k].l,x);

}

void query_sub(int k,int x)

{

         if(k==0)return;

         if(tr[k].v>x)

         {

                   ans=k;query_sub(tr[k].l,x);

         }

         else query_sub(tr[k].r,x);

}

 

usb gadget uvc driver的code分析 uvc的linux driver分为host侧和gadget侧两个driver。host侧的driver在v4l2框架下,而设备侧的driver在usb/gadget文件夹下。gadget侧的uvc driver,利用v4l2框架去注册video_device,向应用层提供调用接口。同时,它完成v4l2 video buffer拷贝到usb request下的buffer下,然后利用uvc实现的协 阅读详情

相关推荐

【Chipyard】Gemmini快速上手

Gemmini 加速器在 ResNet50 推理任务中表现出计算密集型优势,核心操作周期分布符合深度学习模型特征,推理预测流程完整且测试通过,为后续硬件优化和模型部署提供了有效参考。

2354

浅谈无旋treap(fhq_treap)

一、简介 无旋Treap(fhq_treap),是一种不用旋转的treap,其代码复杂度不高,应用范围广(能代替普通treap和splay的所有功能),是一种极其强大的平衡树。 无旋Treap是一个叫做范浩强的大佬发明的(快%啊!) 在我们一起学习无旋Treap之前,本蒟蒻有几句活想说: 1.无旋Treap我个人认为是最容易理解的一种平衡树,而且编程复杂度不高,功能还那么强大。 ...

aaa3201的博客 1646

Plant Simulation 实战指南:从二次分配问题到优化布局设计

本文是一份Plant Simulation实战指南,详细讲解了如何利用该仿真软件解决工厂布局中的二次分配问题。通过从数据准备、模型搭建到集成遗传算法进行自动化优化的完整流程,帮助工程师在数字孪生环境中高效寻找最优设备布局方案,从而显著降低物流成本,提升生产效率。

i1j2k的博客 564

树堆(Treap)图文详解与实现

1.Treap的定义树堆(Treap)是二叉排序树(Binary Sort Tree)与堆(Heap)结合产生的一种拥有堆性质的二叉排序树。但是这里要注意两点,第一点是Treap和二叉堆有一点不同,就是二叉堆必须是完全二叉树,而Treap并不一定是;第二点是Treap并不严格满足平衡二叉排序树(AVL树)的要求,即树堆中每个节点的左右子树高度之差的绝对值可能会超过1,只是近似满足平衡二叉排序树的性质...

Doublelv 的博客专栏。 1万+

NHANES数据库实战:数据合并与加权分析技巧

本文详细解析了NHANES数据库实战中的核心技巧,重点阐述了数据合并与加权分析的正确方法。通过两个具体案例,手把手指导如何从数据下载、合并、权重计算到使用R语言survey包进行加权统计分析,避免因忽略复杂抽样设计而导致的研究偏倚,确保分析结果的准确性与可发表性。

weixin_29057065的博客 585

AI 代码生成工具的质量评估体系

基础需求层包括响应速度(Response Time)和界面友好性(UI Friendliness),期望需求层涵盖智能提示(Smart Suggestions)和个性化配置(Personalization),兴奋需求层则涉及多模态交互(Multimodal Interaction)和代码进化(Code Evolution)。在金融领域,代码审计合规性(Compliance Audit)权重应提升至40%,而在Web开发中,API兼容性(API Compatibility)的权重需达到35%。

2503_92418637的博客 3372

Treap图文详解、效率分析与拓展应用——清华大学计算机系 郭家宝

一、什么是 Treap Treap=Tree+HeapTreap=Tree+HeapTreap=Tree+Heap TreapTreapTreap是一种平衡树 TreapTreapTreap发音为[tri:p] 这个单词的构造选取了TreeTreeTree(树)的前两个字符和HeapHeapHeap(堆)的后三个字符,Treap=Tree+HeapTreap=Tree+HeapTreap=Tree...

良月澪二的博客 6321

MTK(基础篇)ROM烧录以及分区的作用

本文介绍了MTK芯片设备的刷机流程及关键分区功能。首先通过MTK烧录工具加载ROM文件(包括引导文件和分区表),重点解析了各分区的核心作用:preloader类似BIOS负责硬件初始化;lk作为二级引导程序加载内核;vbmeta验证系统完整性;boot包含Linux内核;dtbo调整硬件配置;modem管理通信功能;tee保护生物识别数据;system/vendor分别存放系统核心和硬件驱动。特别指出preloader、vbmeta等关键分区损坏会导致设备变砖,而recovery分区是重要的救砖入口。全文简

weixin_49303682的博客 443

高级搜索-Treap树堆详解

TreapTreeHeapTreapTreeHeap顾名思义,Treap其实就是树和堆的结合,其本质是一种平衡树。我们最基础的BST在插入有序或接近有序的数据时,会退化成单链的结构,所以我们基于BST有着很多优化方案如AVL树引入平衡因子,红黑树引入颜色等等。而我们的Treap引入堆其实就是为了维护平衡。其维护平衡的方法就是在BST的基础上加入修正值,修正值满足最小堆的性质(也可以是最大堆,本文基于最小堆实现),即根的修正值小于其子树的修正值。

EQUINOX1的博客 758

嵌入式开发环境Vscode开发STM32单片机程序

STM32单片机非常强大,大多数教程都是使用 keil 编译器,keil 是收费的而 gcc 是开源免费的。这里介绍一些使用 gcc +开发单片机程序的经验。(这里不解释 gcc 是什么)。

嵌入式技术开发 1842

【自动驾驶轨迹规划之hybrid A*算法】

本文参考论文:https://ai.stanford.edu/~ddolgov/papers/dolgov_gpp_stair08.pdf 这篇文章是基于经典A*算法与reeds-shepp曲线的,不清楚的读者请参考【自动驾驶轨迹规划5之A*算法】_无意2121的博客-优快云博客【自动驾驶轨迹规划之dubins曲线与reeds-shepp曲线】_无意2121的博客-优快云博客 目录 1 hybrid A* 算法创新点 1.1 搜索方式 1.2 车辆运动学模型 1.3 reeds-shepp曲

weixin_65089713的博客 1万+

【图解Treap——平衡树】

Treap-平衡树的讲解纯个人理解

coder-yhh的博客 877

Arduino ESP32 Web服务器从microSD卡读取

Arduino ESP32 Web服务器从microSD卡读取 将网页内容放到SD卡中,当有客户端数据请求时,从SD卡读取信息进行发送,比起SPIFFS文件系统,更节约板上的硬件资源。 SD卡接线说明 ESP32----- SD D5(GPIO 5)-----CS D18(GPIO 18)-----SCK D19(GPIO 19)-----MISO D23()GPIO 23-----MOSI 文件放置 需要把文件放置到SD卡的根目录下。注意SD卡的格式FAT32格式。 实例代码 /*

perseverance51博客 1433

算法导论13-4:Treap

花了一晚上终于解决了《算法导论》13-4 中的思考题 Treap,之前学习的时候就发现这块的内容网上都找不到什么参考资料,面对a---j这几个思考题一筹莫展,今晚静下心来好好研究了下,发现也不是那么难啃。搞算法,就是要沉得住气。

彦祖老师 2633

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

[C++ 学习笔记] FHQ-Treap (无旋 Treap)

C++ FHQ-Treap - 无旋 Treap - 树堆 学习笔记

lzl20220405的博客 3171

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

无旋Treap——FHQ Treap

FHQ Treap

Lucas_FC_的博客 948

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Treap模板

一个新的Treap板子 先放代码 #include<cstdio> #include<cctype> #include<algorithm> #include<functional> template<typename _Tp,typename _Cmp=std::less<_Tp> > class fhq_treap:_Cmp { public: typedef _Tp Value_type;

qq_42722211的博客 270

最强平衡树——Treap[以我的最弱击败你的最强]

以我的最弱战胜你的最强!!——Treap本人蒟蒻,在平衡树坑中深陷数年。为了早日逃离此天坑,特作此文。什么是平衡树?度娘传送门 什么是treap?ACdreamers%%% 注:本篇所有代码都在片尾!!(醒目)CMP那么了解了这些,我们先列出一个list NAME 优势 劣势 splay LCT,序列之王 常数大,代码量稍大 RBT 自适应深度平衡树,速度在同类BS

lemonoil的博客 955

平衡树——treap

一种是要删除的数在叶子节点上,那么我们直接把这个叶子节点的下标修改成0即可,因为我们在上一层传入的是它父节点的tr[u].l或者tr[u].r的引用,所以这里直接赋成0就相当于将它父节点的左指针或者右指针的指向修改成空;通过前三个赋值,我们已经实现了子节点的交换,相对于原来的p的父节点的更新我们该怎么实现了,显然我们没有存父节点的信息, 不能从子节点访问到父节点,但是我们肯定是在递归中实现的,我们只要在递归的时候传入tr[u].l的引用,那么在这一层进行修改的时候就可以实现对tr[u].l的修改。

m0_74120503的博客 1696

Treap + FHQ Treap

一:Treap 支持:插入、删除、查询 xxx 的排名、查询排名为 xxx 的数、查前驱、查后继、左旋右旋 模板题:P3369 【模板】普通平衡树 #include<bits/stdc++.h> #define rint register int #define deb(x) cerr<<#x<<" = "<<(x)<<'\n'; using namespace std; typedef long long ll; typedef pair &lt

Scar_Halo 334

总结-Treap

最近学习了Treap

Continue 2291

非旋treap (fhq treap)

平衡树 非旋treap fhq treap

Josh_Shu_的博客 1170

Treap树

Treap(Tree + Heap)是一种结合二叉搜索树(BST)和堆(Heap)特性的数据结构。每个节点包含两个值:通过随机分配优先级,Treap在期望上能保持平衡,避免普通BST退化为链表的极端情况。插入操作删除操作查找操作 与普通BST相同,时间复杂度为 (O(\log n))(期望)。旋转Treap基础概念 核心逻辑:按照BST规则插入后,通过旋转恢复堆性质。 核心逻辑:通过旋转将待删除节点移至叶子节点后直接删除。 排名定义:小于该值的节点数 + 1。 例题:

2401_88124440的博客 703

treap

treap的讲解网上的版本很多, 这列就不在缀余了,这里主要是讲一下treap中涉及到记录左右儿子个数的旋转,删除,插入: 首先是插入:插入这列基本与裸的TREAP一样,只需要加两句话即可: void insert(int &x,int y)//注意x前面的&。 { if (x==0) { x=++size; ...

weixin_30652897的博客 137

平衡树·从BST到treap到fhq-treap

挖坑

NephrenRuqInsania 678

无旋Treap——从入门到放弃

前言已经是从入门到放弃的第四篇了。 但是本文并不打算给大家讲无旋Treap复杂度证明一类的。 很显然每次操作都是期望Olog(n)的{\bf O}\log(n)的什么是Treap?Treap=Tree+heap 其核心思想在于在权值上维护一棵二叉查找树,在优先级上维护一个堆 有旋treap利用旋转操作来维护堆的性质, 而无旋treap利用有序构树维护堆的性质。无旋Treap的两大构树顺序:

Friedrich_Taylor的博客 5479
上一篇: 并查集(初级)小结
下一篇: 相似图片搜索——感知哈希算法
JinbaoSite0144
博客等级 码龄12年 231粉丝 157原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值