Treap(树堆)
treap是排序二叉树的一种改进,因为排序二叉树有可能会造成链状结构的时候复杂度变成O(n^2)所以通过随机一个优先级的方法来维持每次让优先级最大的作为树根,然后形成一个满足:
A. 节点中的key满足排序二叉树(二叉查找树)
B. 节点中的“优先级”满足大顶堆。
可以证明通过这种方法维持的插入、删除、查找的期望时间复杂度为O(logn)
一、节点的定义:左右孩子用指针数组的形式储存
struct Node{
Node*ch[];//左右子树
int r;//优先值
int v;//值
int cmp(int x) const{
if(x==v)return -;
return x<v?:;//0在ch[0]中正好是左孩子,对应向左搜索和操作,1在ch[1]中是右孩子,对应向右搜索和操作
}
};
二、旋转:和大顶堆的调整方法类似,左旋和右旋,用于对优先级的堆排序,这里不会影响二叉排序树的性质,介绍一种位运算可以巧妙的进行左旋和右旋的选择——异或,相同为0,不同为1,那么x^1就是对x取反的操作。
现在以下图为例
o 表示的指向根节点的指针
有旋转的代码如下:
//左旋代码
k = o->ch[];
o->ch[] = k->ch[];
k->ch[] = o;
o = k;
//右旋代码
k = o->ch[];
o->ch[] = k->ch[];
k->ch[] = o;
o = k;
//两种代码可以写成一种,利用异或
void rotate(Node* &o,int d){//d = 0 左旋,d = 1 右旋
Node *k = o->ch[d^];
o->ch[d^] = k->ch[d];
k->ch[d] = o;
o = k;
}
三、插入: 在插入的时候除了要在满足排序二叉树的插入要求,即递归的操作之外,还要满足堆的相应操作,所以,要通过旋转来实现,下面是代码:
srand(time(NULL));
void insert(Node *&o, int x){
if(o==NULL){
o = new Node();
o->ch[] = o->ch[] = NULL;
o->v = x;
o->r = rand();
}
else {
int d = o->cmp(x);//如果要插入的值x比当前根节点的值小则d==0,向左子树寻找,这里可以看出定义指针数组的好处
insert(o->ch[d],x);
if(o->ch[d]->r > o->r) rotate(o,d^);//左孩子权值大右旋,右孩子权值大左旋
}
}
四、删除:如果待删除结点为叶子结点或只有一棵子树,则用其子树(可能为空)替代它即可。如果有两棵子树,则将孩子中优先级高的旋转到根,然后在另一棵子树中递归删除目标点。
代码如下:
void remove(Node *&o,int x){
int d = o->cmp(x);
if(d==-){//找到了
if(o->ch[] == NULL) o = o->ch[];
else if(o->ch[] == NULL) o = o->ch[];
else {
int d2 = ((o->ch[]->r)>(o->ch[]->r)?:);//删除节点的左孩子权值大右旋,右孩子权值大左旋
rotate(o,d2);
remove(o->ch[d2],x);
}
}
else remove(o->ch[d],x);
}
五、查找:在插入和查找前进行查找,防止特殊情况,代码如下
int find(Node*o, int x){
while(o!=NULL){
int d = o->cmp(x);
if(d==-) return ;//找到了
else o = o->ch[d];
}
return ;//不存在
}
六、应用,这个数据结构可以用来解决二叉排序树的超时问题
Treap(树堆)的更多相关文章
- BZOJ3224/LOJ104 普通平衡树 treap(树堆)
您需要写一种数据结构,来维护一些数,其中需要提供以下操作:1. 插入x2. 删除x(若有多个相同的数,因只删除一个)3. 查询x的排名(若有多个相同的数,因输出最小的排名)4. 查询排名为x的数5. ...
- 可旋转Treap(树堆)总结
树堆,在数据结构中也称Treap,是指有一个随机附加域满足堆的性质的二叉搜索树,其结构相当于以随机数据插入的二叉搜索树.其基本操作的期望时间复杂度为O(logn).相对于其他的平衡二叉搜索树,Trea ...
- treap(树堆)
一棵treap是一棵修改了结点顺序的二叉查找树,如图,显示一个例子,通常树内的每个结点x都有一个关键字值key[x],另外,还要为结点分配priority[x],它是一个独立选取的随机数. 假设所有的 ...
- 查找——图文翔解Treap(树堆)
之前我们讲到二叉搜索树,从二叉搜索树到2-3树到红黑树到B-树. 二叉搜索树的主要问题就是其结构与数据相关,树的深度可能会非常大,Treap树就是一种解决二叉搜索树可能深度过大的还有一种数据结构. T ...
- 树堆(Treap)学习笔记 2020.8.12
如果一棵二叉排序树的节点插入的顺序是随机的,那么这样建立的二叉排序树在大多数情况下是平衡的,可以证明,其高度期望值为 \(O( \log_2 n )\).即使存在一些极端情况,但是这种情况发生的概率很 ...
- Treap树的基础知识
原文 其它较好的的介绍:堆排序 AVL树 树堆,在数据结构中也称Treap(事实上在国内OI界常称为Traep,与之同理的还有"Tarjan神犇发明的"Spaly),是指有一个随 ...
- Treap树
Treap树算是一种简单的优化策略,这名字大家也能猜到,树和堆的合体,其实原理比较简单,在树中维护一个"优先级“,”优先级“ 采用随机数的方法,但是”优先级“必须满足根堆的性质,当然是“大根 ...
- 6天通吃树结构—— 第三天 Treap树
原文:6天通吃树结构-- 第三天 Treap树 我们知道,二叉查找树相对来说比较容易形成最坏的链表情况,所以前辈们想尽了各种优化策略,包括AVL,红黑,以及今天 要讲的Treap树. Treap树算是 ...
- Treap树 笔记
预备知识:二叉查找树.堆(heap).平衡二叉树(AVL)的基本操作(左旋右旋) 定义: Treap.平衡二叉树.Tree+Heap.树堆. 每个结点两个键值(key.priority). 性质1. ...
- 真·浅谈treap树
treap树是一种平衡树,它有平衡树的性质,满足堆的性质,是二叉搜索树,但是我们需要维护他 为什么满足堆的性质?因为每个节点还有一个随机权值,按照随机权值维持这个堆(树),可以用O(logn)的复杂度 ...
随机推荐
- ArcGIS 网络分析[2.4] OD成本矩阵
什么是OD成本矩阵? 先不说这个东西是什么,我们还是举一个实际的例子: 现在存在3个城市北京.上海.武汉,请分析他们两两之间的通行时间. 很简单嘛!北京到上海,北京到武汉,上海到武汉都来一次最短路径分 ...
- nova创建虚拟机源码分析系列之四 nova代码模拟
在前面的三篇博文中,介绍了restful和SWGI的实现.结合restful和WSGI配置就能够简单的实现nova服务模型的最简单的操作. 如下的内容是借鉴网上博文,因为写的很巧妙,将nova管理虚拟 ...
- ES6 函数的扩展2
8.2 rest参数 ES6引入rest参数(形式为"-变量名"),用于获取函数的多余参数,这样就不需要使用arguments对象了. arguments对象并没有数组的方法,re ...
- lesson - 9 课程笔记
一. yum 作用: yum 命令是在Fedora 和RedHat 以及SUSE 中基于rpm 的软件包管理器,它可以使系统管理人员交互和自动 ...
- lesson - 3 笔记 ls /alias /ldd /cd /pwd /环境变量 / 目录
一.ls 命令 作用:用来显示目录列表. 语法: ls (选项) (参数) 选项: -a: 显示所有档案以及目录(ls内定将档案或目录名称为“./..”的视为隐藏) -A: 显示除隐藏文件“./.. ...
- 英雄联盟LOL用什么语言写的?
是用openGL开发的 开发语言是c/c++ 客户端是一个.net的web界面
- MySQL index 增删改
一.前提信息 1.数据库版本 mysql> select version(),user(); +------------+----------------+ | version() | user ...
- 利用伪元素:after清除浮动
一.代码 html代码 <div class="clearfix"></div> css样式 .clearfix{ zoom:1;/*这个属性是为了兼容IE ...
- beanstalk 安装
1.安装 # wget https://github.com/kr/beanstalkd/archive/v1.10.tar.gz # tar xzvf v1.10 # cd beanstalkd-1 ...
- windows安装ipython的困难重重
本机环境 系统: windows 10 64位 python版本:3.2.1 安装过程 安装ipython可以使用python的pip工具 pip install ipython 在使用pip前,我准 ...