本文是根据郭家宝的文章《Treap的原理及实现》写的。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct node{
struct node *left,*right;
int data,fix,size,weight;
node(int x){
data=x;
weight=size=;
fix=rand();
left=right=NULL;
}
void updata_size(){
size=weight+lsize()+rsize();
}
int lsize(){return left?left->size:;}
int rsize(){return right?right->size:;}
};
void right_rotate(node* &p){//右旋
node* t=p->left;
p->left=t->right;
t->right=p;
p->updata_size();
t->updata_size();
p=t;
}
void left_rotate(node* &p){//×óÐý
node* t=p->right;
p->right=t->left;
t->left=p;
p->updata_size();
t->updata_size();
p=t;
}
void insert(node* &p,int x){//左旋
if(p&&p->data==x){
p->weight++;
p->size++;
return ;
}
if(!p){
p=new node(x);
}else if(x<p->data){
insert(p->left,x);
if(p->left->fix<p->fix)
right_rotate(p);
}else{
insert(p->right,x);
if(p->right->fix<p->fix)
left_rotate(p);
}
p->updata_size();
}
int find(node* p,int x){//查找
if(!p) return ;
if(p->data==x) return ;
if(p->data>x)
return find(p->left,x);
else
return find(p->right,x);
}
void Delete(node* &p,int x){//删除
if(p->data==x){
if(--p->weight==){
if(!p->left||!p->right){
node* t=p;
if(!p->right)
p=p->right;
else
p=p->left;
delete p;
}else{
if(p->left->fix<p->right->fix){
right_rotate(p);
Delete(p->right,x);
}else{
left_rotate(p);
Delete(p->left,x);
}
}
}
}else if(p->data>x){
Delete(p->left,x);
}else{
Delete(p->right,x);
}
if(p) p->updata_size();
}
void mid_print(node* p){//中序
if(p){
mid_print(p->left);
printf("%d ",p->data);
mid_print(p->right);
}
}
node* Pre(node* p,int x,node* opt){//前缀
if(!p) return opt;
if(p->data<=x) return Pre(p->right,x,p);
else return Pre(p->left,x,opt);
}
node* Suf(node* p,int x,node* opt){//后继
if(!p) return opt;
if(p->data>=x) return Suf(p->left,x,p);
else return Suf(p->right,x,opt);
}
node* Kth(node* p,int k){//Kth
if(k<=p->lsize()) return Kth(p->left,k);
else if(k>p->lsize()+p->weight) return Kth(p->right,k-(p->lsize()+p->weight));
else return p;
}
int rand(node* p,int x,int cur){//排名
if(x==p->data) return cur+p->lsize()+;
else if(x<p->data) return rand(p->left,x,cur);
else return rand(p->right,x,cur+p->lsize()+p->weight);
}
int main(){
node* root;
case :insert(root,x);
case :if(find(root,x))Delete(root,x);
case :mid_print(root);
case :printf("%d\n",Pre(root,x,)->data);
case :printf("%d\n",Suf(root,x,)->data);
case :printf("%d\n",Kth(root,k)->data);
case :printf("%d\n",rank(root,x));
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(树堆) 学习笔记

    调了好几个月的 Treap 今天终于调通了,特意写篇博客来纪念一下. 0. Treap 的含义及用途 在算法竞赛中很多题目要使用二叉搜索树维护信息.然而毒瘤数据可能让二叉搜索树退化成链,这时就需要让二 ...

  7. Treap树 笔记

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

  8. 真·浅谈treap树

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

  9. Treap树的基础知识

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

  10. Treap树

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

随机推荐

  1. Oracle 中 call 和 exec的区别

    今天发现了一个小东西,觉得很有意思,查找了一些资料,跟大家分享一下: 在sqlplus中: 在第三方提供的工具(如:plsqldev) 总结: exec是sqlplus的命令,只能在sqlplus中使 ...

  2. ALV用例大全

    一.ALV介绍  The ALV Grid Control (ALV = SAP List Viewer)是一个显示列表的灵活的工具,它提供了基本功能的列表操作,也可以通过自定义来进行增强,因此可以允 ...

  3. Thread.CurrentPrincipal & HttpContext.Current.User

    据说要这样写才稳妥 // This principal will flow throughout the request.VoyagerPrincipal principal = new Voyage ...

  4. Opengles 管线编程介绍

      OpenGL ES 2.0可编程管道 上图橙色部分(Vertex Shader和Fragment Shader)为此管道的可编程部分.整个管道包含以下两个规范: 1)         OpenGL ...

  5. Android 缓存目录 Context.getExternalFilesDir()和Context.getExternalCacheDir()方法

    一.基础知识 应用程序在运行的过程中如果需要向手机上保存数据,一般是把数据保存在SDcard中的.大部分应用是直接在SDCard的根目录下创建一个文件夹,然后把数据保存在该文件夹中.这样当该应用被卸载 ...

  6. C++pair类型

    标准库类型--pair类型定义在utility头文件中定义 本文地址:http://www.cnblogs.com/archimedes/p/cpp-pair.html,转载请注明源地址. 1.pai ...

  7. Unity与Android的相互交互

    1.Unity调用Android. Unity块代码: using (AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.play ...

  8. iOS9 HTTP 不能正常使用的解决办法

    Google后查证,iOS9引入了新特性App Transport Security (ATS).详情:App Transport Security (ATS) 新特性要求App内访问的网络必须使用H ...

  9. iOSQuartz2D-01-核心要点

    简介 作用 绘制 绘制图形 : 线条\三角形\矩形\圆\弧等 绘制文字 绘制\生成图片(图像) 读取\生成PDF 截图\裁剪图片 自定义UI控件(通常为内部结构较复杂的控件) UIKit中的绝大部分控 ...

  10. android 进程间通信---Service Manager(2)

    关于servicemanager的设计: 还是这张结构图,由于ProcessState & IPCThreadState是与binder deriver交互的, 所以对于client端来说Bp ...