【平衡树】Treap

  • treap=tree+heap;
    就是在一颗平衡树上维护一个fix域,使得这棵树如果以key值域看的话是一颗排序树,以fix域看是一个堆。这样利用平均分布的fix值使得这棵树相对平衡。
    平衡树里相对好写的就是treap和SBT了,改天膜拜下sbt去。
    今天先说treap。
  • 写法
    顾名思义就是在平衡树的基础上加了一个堆得维护,(堆都会写吧)
    插入删除时记得利用旋转来让孩子的fix值跟父节点的大小关系不变(大根堆小根堆都可以吧)。

好像就没有什么了……..

  • P.S.
    这里的fix是随机数,不是给定的值,给定fix的treap是笛卡尔树。
    (md学校评测不让用rand()…..我怎么玩)

废话不多说,上代码…..
我按这个写的,附上原po

#include <iostream>
#include <cstdio>
#include <climits>
#include <cstdlib>
using namespace std;
class treap{
    public:
    int key,size,fix;
    treap* ch[2];
    void maintain(){
        size=1;
        if(ch[0]!=NULL) size+=ch[0]->size;
        if(ch[1]!=NULL) size+=ch[1]->size;
    }
    treap(int key){
        this->key=key,size=1,fix=rand(),ch[1]=ch[0]=NULL;
    }
    int compare(int x){if(key==x) return -1;else return key>x?0:1;}
    void rotate(treap* &t,int d){
        treap *k=t->ch[d^1];
        t->ch[d^1]=k->ch[d];
        k->ch[d]=t;
        t->maintain(),k->maintain();
        t=k;
    }
    void insert(treap* &t,int x){
        if(t==NULL) t=new treap(x);
        else{
            int d=x>t->key;
            insert(t->ch[d],x);
            if(t->ch[d]->fix>t->fix)
                rotate(t,d^1);
        }
        t->maintain();
    }
    void del(treap* &t,int x){
        int d=t->compare(x);
        if(d==-1){
            treap *temp=t;
            if(t->ch[0]==NULL){
                t=t->ch[1];
                delete temp;
                temp=NULL;
            }
            else if(t->ch[1]==NULL){
                t=t->ch[0];
                delete temp;
                temp=NULL;
            }
            else{
                int k=t->ch[0]->fix>t->ch[1]->fix?1:0;
                rotate(t,k);
                del(t->ch[k],x);
            }
        }
        else del(t->ch[d],x);
        if(t!=NULL) t->maintain();
    }
    bool find(treap *t,int x){
        while(t!=NULL){
            int d=t->compare(x);
            if(d==-1) return 1;
            t=t->ch[d];
        }
        return 0;
    }
    int kth(treap *t,int k){
        if(t==NULL||k<=0||k>t->size)
            return -1;
        if(t->ch[0]==NULL&&k==1)
            return t->key;
        if(t->ch[0]==NULL)
            return kth(t->ch[1],k-1);
        if(t->ch[0]->size>=k)
            return kth(t->ch[0],k);
        if(t->ch[0]->size+1==k)
            return t->key;
        return kth(t->ch[1],k-1-t->ch[0]->size);
    }
    int rank(treap *t,int x){
        int r;
        if(t->ch[0]==NULL) r=0;
        else r=t->ch[0]->size;
        if(x==t->key) return r+1;
        if(x<t->key)
            return rank(t->ch[0],x);
        return r+1+rank(t->ch[1],x);
    }
    void delete_treap(treap* &t){
        if(t==NULL) return;
        if(t->ch[0]!=NULL) delete_treap(t->ch[0]);
        if(t->ch[1]!=NULL) delete_treap(t->ch[1]);
        delete t;
        t=NULL;
    }
};
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值