平衡树treap的基本操作
也是一棵平衡树所以要旋转
(pri,key);
左边小右边大 key
pri 符合堆 实现log 的操作
#include<stdio.h> #include<algorithm> #include<stdlib.h> #include<cstring> #include<iostream> #include<string> #include<cmath> #include<vector> #include<queue> #include<map> #include<iterator> #include<stack> using namespace std; #define ll long long #define MAXN 100010 #define inf 2000000007 struct node { struct node *ch[2]; int key,sz,pri; }; typedef struct node *tree; node base[MAXN],nil; tree top,root,null; void Init() //初始化 { top=base; root=null=&nil; null->ch[0]=null->ch[1]=null; null->key=null->pri=2147483647; null->sz=0; } inline int random()//随机 { static int seed=703; return seed=int(seed*48271ll%2147483647); } inline tree newnode(int k)//产生新的点 { top->key=k; top->sz=1; top->pri=random(); top->ch[0]=top->ch[1]=null; return top++; } void Rotate(tree &x,bool d) //旋转 { tree y=x->ch[!d]; x->ch[!d]=y->ch[d]; y->ch[d]=x; x->sz=x->ch[0]->sz+1+x->ch[1]->sz; y->sz=y->ch[0]->sz+1+y->ch[1]->sz; x=y; } void Insert(tree &t,int key) //插入 { if(t==null) t=newnode(key); else { bool d=key>t->key; Insert(t->ch[d],key); //先到叶子再旋转 (t->sz)++; if(t->pri<t->ch[d]->pri) Rotate(t,!d); } } void Delete(tree &t,int key)//删除 { if(t->key!=key) { Delete(t->ch[key>t->key],key); (t->sz)--; } else if(t->ch[0]==null) t=t->ch[1]; else if(t->ch[1]==null) t=t->ch[0]; else { bool d=t->ch[0]->pri<t->ch[1]->pri; Rotate(t,d); Delete(t->ch[d],key); } } tree select(int k) { tree t=root; int tmp; for(;;) { tmp=t->ch[0]->sz+1; if(k==tmp) .//这个点 return t; else if(k>tmp)//右孩子 { k-=tmp; t=t->ch[1]; } else//左边 t=t->ch[0]; } } int main() { Init(); Insert(root,1); printf("1\n"); Insert(root,2); Insert(root,3); Insert(root,-1); Delete(root,2); printf("%d\n",select(2)->key); return 0; }
posted on 2017-04-15 15:30 HelloWorld!--By-MJY 阅读(126) 评论(0) 编辑 收藏 举报