平衡树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;
}
View Code

 

posted on 2017-04-15 15:30  HelloWorld!--By-MJY  阅读(126)  评论(0编辑  收藏  举报

导航