具有随机性的平衡树——treap

简而言之,treap=tree+heap,首先它是一棵二叉树,其次treap中每个节点含有一个优先级的值,这些值随机给定,但整棵树中的这些值满足大根堆(或小根堆的性质)。

左旋与右旋操作跟其他平衡树一样。

插入操作:首先将新节点插入到叶子节点位置(与普通排序二叉树一样),然后由于插入后可能破坏了heap的性质,这个时候需要对新插入节点的根节点进行左旋或右旋,一直调整到符合heap性质为止。

删除操作:将需要删除的节点旋转到叶子节点或者只有一个孩子的位置,然后删掉就可以了。

关于size,用treap来维护节点的size域(即以某节点为根的子树中节点的个数)是非常方便的,加一个maintain操作即可。

// 不带size域的treap
class Treap {
public:
    const static int MaxN = 100000;
    int root, tsize, l[MaxN], r[MaxN], p[MaxN];
    int key[MaxN];

    void rot_l(int &x) {    //before using this function, please ensure that the right son of x exist
        int tmp = r[x];
        r[x] = l[tmp]; l[tmp] = x;
        x = tmp;
    }
    void rot_r(int &x) {    //before using this function, please ensure that the left son of x exist
        int tmp = l[x];
        l[x] = r[tmp]; r[tmp] = x;
        x = tmp;
    }
    Treap():root(-1),tsize(-1) {}
    void insert(int &root, const int &x) {
        if(root == -1) {
            key[++tsize] = x;
            root = tsize;
            p[root] = rand();
            l[root] = r[root] = -1;
        }
        else if(x <= key[root]) {
            insert(l[root], x);
            if(p[l[root]] > p[root])  rot_r(root);
        }
        else {
            insert(r[root], x);
            if(p[r[root]] > p[root])  rot_l(root);
        }
    }
    void del(int &root, const int &x) {
        if(key[root] == x) {
            if(l[root]==-1 && r[root]==-1)  root = -1;
            else if(l[root] == -1)  root = r[root];
            else if(r[root] == -1)  root = l[root];
            else {
                if(p[l[root]] > p[r[root]]) {
                    rot_r(root);
                    del(r[root], x);
                }
                else {
                    rot_l(root);
                    del(l[root], x);
                }
            }
        }
        else if(x < key[root])  del(l[root], x);
        else del(r[root], x);
    }
    bool find(int &root, const int &x) {
        if(root == -1)  return  false;
        if(x == key[root])  return  true;
        else if(x < key[root])  return  find(l[root], x);
        else return  find(r[root], x);
    }
};
//带size的treap
class Treap {
public:
    const static int MaxN = 100000;
    int root, tsize, l[MaxN], r[MaxN], p[MaxN], nsize[MaxN];
    int key[MaxN];

    void maintain(const int &root) {
        int ta, tb;
        ta = l[root]==-1? 0 : nsize[l[root]];
        tb = r[root]==-1? 0 : nsize[r[root]];
        nsize[root] = ta+tb+1;
    }
    void rot_l(int &x) {    //before using this function, please ensure that the right son of x exist
        int tmp = r[x];
        r[x] = l[tmp]; maintain(x);
        l[tmp] = x; x = tmp; maintain(x);
    }
    void rot_r(int &x) {    //before using this function, please ensure that the left son of x exist
        int tmp = l[x];
        l[x] = r[tmp]; maintain(x);
        r[tmp] = x; x = tmp; maintain(x);
    }
    Treap():root(-1),tsize(-1) {}
    void insert(int &root, const int &x) {
        if(root == -1) {
            key[++tsize] = x;
            root = tsize;
            p[root] = rand();
            l[root] = r[root] = -1;
            nsize[root] = 1;
        }
        else if(x <= key[root]) {
            insert(l[root], x);
            if(p[l[root]] > p[root])  rot_r(root);
        }
        else {
            insert(r[root], x);
            if(p[r[root]] > p[root])  rot_l(root);
        }
        maintain(root);
    }
    void del(int &root, const int &x) {
        if(key[root] == x) {
            if(l[root]==-1 && r[root]==-1)  root = -1;
            else if(l[root] == -1)  root = r[root];
            else if(r[root] == -1)  root = l[root];
            else {
                if(p[l[root]] > p[r[root]]) {
                    rot_r(root);
                    del(r[root], x);
                }
                else {
                    rot_l(root);
                    del(l[root], x);
                }
            }
        }
        else if(x < key[root])  del(l[root], x);
        else del(r[root], x);
        if(root != -1)  maintain(root);
    }
    int kthElement(const int &root, int k) {
        int ta;
        ta = l[root]==-1? 0 : nsize[l[root]];
        if(ta >= k)  return  kthElement(l[root], k);
        else if(ta+1 == k)  return  key[root];
        else  return  kthElement(r[root], k-ta-1);
    }
    bool find(int &root, const int &x) {
        if(root == -1)  return  false;
        if(x == key[root])  return  true;
        else if(x < key[root])  return  find(l[root], x);
        else return  find(r[root], x);
    }
};

 

 

 

posted @ 2013-04-05 21:22  A&C  阅读(257)  评论(0编辑  收藏  举报