Treap简介
来源:互联网 发布:剑指offer python 编辑:程序博客网 时间:2024/06/17 18:39
定义
树堆,在数据结构中也称Treap,是指有一个随机附加域满足堆的性质的二叉搜索树,其结构相当于以随机数据插入的二叉搜索树。
简单点说,Treap=tree+heap
实现
Treap实际上是对BST的优化。因为BST有可能退化成链而导致查询复杂度变成
而维护heap时需要旋转操作,这里给一张图体会一下:
那heap这个性质是怎么来的呢?
在插入一个节点时,我们随机地给它一个优先级,然后和维护heap一样维护这个优先级。插入时如果优先级比根大就旋转。删除时和插入反过来就可以了,把需要删除的节点不断旋转至叶子节点,然后删去即可。
操作
由于Treap的本质就是BST,因此它支持BST的所有操作。
代码实现(模板)
以BZOJ3224(洛谷P3369)为例:
#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#define N 100000using namespace std;struct node{ int w,p,size,rnd,to[2]; //w:权值 p:有多少权值是相等的 size:子树中的节点个数 //rnd:优先级 to[]:儿子}t[N+5];int n,rt,nd,p;void rtt(int &x,int fl){//rotate(旋转) int s=t[x].to[fl]; t[x].to[fl]=t[s].to[fl^1]; t[s].to[fl^1]=x; t[s].size=t[x].size; t[x].size=t[t[x].to[0]].size+t[t[x].to[1]].size+t[x].p; x=s; return;}void nsrt(int &x,int w){//insert(插入) if (!x){ t[x=++nd].w=w; t[x].rnd=rand(); t[x].p=t[x].size=1; return; } t[x].size++; if (t[x].w==w) t[x].p++; else if (t[x].w<w){ nsrt(t[x].to[1],w); if (t[t[x].to[1]].rnd<t[x].rnd) rtt(x,1); } else{ nsrt(t[x].to[0],w); if (t[t[x].to[0]].rnd<t[x].rnd) rtt(x,0); }}void dlt(int &x,int w){//delete(删除) if (!x) return; if (t[x].w==w){ if (t[x].p>1){ t[x].p--; t[x].size--; return; } if (!(t[x].to[0]*t[x].to[1])) x=t[x].to[0]+t[x].to[1]; else if (t[t[x].to[0]].rnd<t[t[x].to[1]].rnd) rtt(x,0),dlt(x,w); else rtt(x,1),dlt(x,w); } else{ t[x].size--; if (t[x].w<w) dlt(t[x].to[1],w); else dlt(t[x].to[0],w); }}int srch_rk(int x,int w){//search_rank(查询排名) if (!x) return 0; if (t[x].w==x) return t[t[x].to[0]].size+1; else if (t[x].w<w) return t[t[x].to[0]].size+t[x].p+srch_rk(t[x].to[1],w); else return srch_rk(t[x].to[0],w);}int srch_nm(int x,int w){//search_num(查询数) if (!x) return 0; if (t[t[x].to[0]].size>=w) return srch_nm(t[x].to[0],w); else if (t[t[x].to[0]].size+t[x].p<w) return srch_nm(t[x].to[1],w-t[t[x].to[0]].size-t[x].p); else return t[x].w;}int srch_frnt(int x,int w){//search_front(查询前驱) if (!x) return 0; if (t[x].w<w){ int k=srch_frnt(t[x].to[1],w); if (!k) return t[x].w; else return k; } else return srch_frnt(t[x].to[0],w);}int srch_bck(int x,int w){//search_back(查询后继) if (!x) return 0; if (t[x].w>w){ int k=srch_bck(t[x].to[0],w); if (!k) return t[x].w; else return k; } else return srch_bck(t[x].to[1],w);}int main(){ scanf("%d",&n); for (int i=1;i<=n;i++){ int flag,x; scanf("%d%d",&flag,&x); switch (flag){ case 1: nsrt(rt,x); break; case 2: dlt(rt,x); break; case 3: printf("%d\n",srch_rk(rt,x)+1); break;//这里记得+1 case 4: printf("%d\n",srch_nm(rt,x)); break; case 5: printf("%d\n",srch_frnt(rt,x)); break; case 6: printf("%d\n",srch_bck(rt,x)); break; } } return 0;}
阅读全文
1 0
- Treap简介
- 数据结构之:treap 简介(一)
- 数据结构之:treap 简介(二)
- 笛卡尔树简介(分类到treap里面)
- Treap
- Treap
- Treap
- Treap
- Treap
- Treap
- treap
- Treap
- treap
- Treap
- treap
- Treap
- Treap
- treap
- Wannafly挑战赛4 B 小AA的数列
- 易宝支付的客户端加密工具类DigestUtil.java
- Unity SceneView 鼠标所在网格位置
- NP问题
- 冒泡排序
- Treap简介
- react基础demo
- 第十二周 【项目5
- 11月英语总结
- 每日一练-12
- Hadoop+spark+hive全分布环境的搭建
- 走穿java23钟设计模式-11外观模式
- 一个有趣python self的题目
- 第十三周 【项目1