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

  1. BZOJ3224/LOJ104 普通平衡树 treap(树堆)

    您需要写一种数据结构,来维护一些数,其中需要提供以下操作:1. 插入x2. 删除x(若有多个相同的数,因只删除一个)3. 查询x的排名(若有多个相同的数,因输出最小的排名)4. 查询排名为x的数5. ...

  2. 可旋转Treap(树堆)总结

    树堆,在数据结构中也称Treap,是指有一个随机附加域满足堆的性质的二叉搜索树,其结构相当于以随机数据插入的二叉搜索树.其基本操作的期望时间复杂度为O(logn).相对于其他的平衡二叉搜索树,Trea ...

  3. treap(树堆)

    一棵treap是一棵修改了结点顺序的二叉查找树,如图,显示一个例子,通常树内的每个结点x都有一个关键字值key[x],另外,还要为结点分配priority[x],它是一个独立选取的随机数. 假设所有的 ...

  4. 查找——图文翔解Treap(树堆)

    之前我们讲到二叉搜索树,从二叉搜索树到2-3树到红黑树到B-树. 二叉搜索树的主要问题就是其结构与数据相关,树的深度可能会非常大,Treap树就是一种解决二叉搜索树可能深度过大的还有一种数据结构. T ...

  5. 树堆(Treap)学习笔记 2020.8.12

    如果一棵二叉排序树的节点插入的顺序是随机的,那么这样建立的二叉排序树在大多数情况下是平衡的,可以证明,其高度期望值为 \(O( \log_2 n )\).即使存在一些极端情况,但是这种情况发生的概率很 ...

  6. Treap树的基础知识

    原文 其它较好的的介绍:堆排序  AVL树 树堆,在数据结构中也称Treap(事实上在国内OI界常称为Traep,与之同理的还有"Tarjan神犇发明的"Spaly),是指有一个随 ...

  7. Treap树

    Treap树算是一种简单的优化策略,这名字大家也能猜到,树和堆的合体,其实原理比较简单,在树中维护一个"优先级“,”优先级“ 采用随机数的方法,但是”优先级“必须满足根堆的性质,当然是“大根 ...

  8. 6天通吃树结构—— 第三天 Treap树

    原文:6天通吃树结构-- 第三天 Treap树 我们知道,二叉查找树相对来说比较容易形成最坏的链表情况,所以前辈们想尽了各种优化策略,包括AVL,红黑,以及今天 要讲的Treap树. Treap树算是 ...

  9. Treap树 笔记

    预备知识:二叉查找树.堆(heap).平衡二叉树(AVL)的基本操作(左旋右旋) 定义: Treap.平衡二叉树.Tree+Heap.树堆. 每个结点两个键值(key.priority). 性质1. ...

  10. 真·浅谈treap树

    treap树是一种平衡树,它有平衡树的性质,满足堆的性质,是二叉搜索树,但是我们需要维护他 为什么满足堆的性质?因为每个节点还有一个随机权值,按照随机权值维持这个堆(树),可以用O(logn)的复杂度 ...

随机推荐

  1. 常用的 JS 排序算法整理

    关于排序算法的问题可以在网上搜到一大堆,但是纯 JS 版比较零散,之前面试的时候特意整理了一遍,附带排序效率比较. //1.冒泡排序 var bubbleSort = function(arr) { ...

  2. Servlet小总结

    Servlet Servlet(服务器端小程序)是使用Java语言编写的服务器端程序,像JSP一样,生成动态的Web页.Servlet主要运行在服务器端,并由服务器调用执行. Servlet处理的基本 ...

  3. scala写算法-List、Stream、以及剑指Offer里部分题目基于scala解法

    Stream(immutable) Stream是惰性列表.实现细节涉及到lazy懒惰求值.传名参数等等技术(具体细节详见维基百科-求值策略). Stream和List是scala中严格求值和非严格求 ...

  4. Golang 网络爬虫框架gocolly/colly 二 jQuery selector

    Golang 网络爬虫框架gocolly/colly 二 jQuery selector colly框架依赖goquery库,goquery将jQuery的语法和特性引入到了go语言中.如果要灵活自如 ...

  5. Mac_OS_Sierra_10.12.6编译OpenJDK9

    编译环境以及依赖 macOS:Sierra,10.12.6 处理器:2.6 GHz Intel Core i7 内存:16 GB 2133 MHz LPDDR3 Command Line Tools ...

  6. 【ASP.NET Core】运行原理(4):授权

    本系列将分析ASP.NET Core运行原理 [ASP.NET Core]运行原理(1):创建WebHost [ASP.NET Core]运行原理(2):启动WebHost [ASP.NET Core ...

  7. springBoot系列教程05:fastjson的集成、配置及使用

    springBoot自带的json用着不太习惯,已习惯了fastJSON,下面介绍下fastjson的配置 1. pom引入 <dependency> <groupId>com ...

  8. Not using bundled FreeTDS (error: command 'gcc' failed with exit status 1)

    # Wget https://pypi.python.org/packages/4c/c8/5ad36d8d3c304ab4f310c89d0593ab7b6229568dd8e9cde927311b ...

  9. robotframework的学习笔记(十二)------DatabaseLibrary 库

    1.安装DatabaseLibrary库 DatabaseLibrary 下载地址:https://pypi.python.org/pypi/robotframework-databaselibrar ...

  10. python 发信实例

    转自:http://www.cnblogs.com/lonelycatcher/archive/2012/02/09/2343463.html 文件形式邮件   #!/usr/bin/env pyth ...