博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

Treap模板+Treap介绍C++

reap 是一种平衡树。Treap 发音为[ ]。这个单词的构造选 取了 Tree(树)的前两个字符和 Heap(堆)的后三个字符,Treap = Tree + Heap。顾名思义,Treap 把 BST 和 Heap 结合了起来。它和 BST 一样满足许多优美的性质,而引入堆目的就是为了维护平衡。


以上是基本的介绍,具体一点是这样,Treap 可以定义为有以下性质的二叉树:
1. 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值,而且它的根节点 的修正值小于等于左子树根节点的修正值;
2. 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值,而且它的根节点 的修正值小于等于右子树根节点的修正值;
3. 它的左、右子树也分别为 Treap。


Treap的维护主要是通过左旋和右旋实现的,为了把左孩子或者右孩子变成父亲,具体是这样操作。
左旋和右旋


来举个例子,如图所示的左边的一个 Treap,它仍然满足 BST 性质。但是由于某些原因,节点 4 和节点 2 之间不满足最小堆序,4 作为 2 的父节点,它的修正值大于左子节点的修正值。我们只有 将 2 变成 4 的父节点,才能维护堆序。根据旋转的性质我们可以知道,由于 2 是 4 的左子节 点,为了使 2 成为 4 的父节点,我们需要把以 4 为根的子树右旋。右旋后,2 成为了 4 的父 节点,满足堆序。
这里写图片描述


Insert和Delete操作都和BST和HEAP很像,具体看代码咯。


struct Treapnode
{
    Treapnode *left,*right;
    int value,fix;
};
Treapnode *root;
void Treapleft(Treapnode *&a)
{
    Treapnode *b=a->right;
    a->right=b->left;
    b->left=a;
    a=b;
}
void Treapright(Treapnode *&a)
{
    Treapnode *b=a->left;
    a->left=b->right;
    b->right=a;
    a=b;
}
Treapnode *Treapfind(Treapnode *p,int value)
{
    if(!p)
        return 0;
    if(p->value==value)
        return p;
    if(p->value<value)
        return Treapfind(p->left,value);
    else
        return Treapfind(p->right,value);
}
void Treapprint(Treapnode *p)
{
    if(p)
    {
        Treapprint(p->left);
        printf("%d",p->value);
        Treapprint(p->right);
    }
}
void Treapinsert(Treapnode *&p,int value)
{
    if(!p)
    {
        p=new Treapnode;
        p->value=value;
        p->fix=rand();
    }
    else
    {
        if(value<=p->value)
        {
            Treapinsert(p->left,value);
            if(p->left->fix<p->fix)
                Treapright(p);
        }
        else
        {
            Treapinsert(p->right,value);
            if(p->right->fix<p->fix)
                Treapleft(p);
        }
    }
}
void Treapdelete(Treapnode *&p,int value)
{
    if(p->value==value)
    {
        if(!(p->left) || !(p->right))
        {
            Treapnode *t=p;
            if(p->left)
                p=p->left;
            else
                p=p->right;
            delete t;
        }
        else
        {
            if(p->left->fix<p->right->fix)
            {
                Treapright(p);
                Treapdelete(p->right,value);
            }
            else
            {
                Treapleft(p);
                Treapdelete(p->left,value);
            }
        }

    }
    else
    {
        if(value<p->value)
            Treapdelete(p->left,value);
        else
            Treapdelete(p->right,value);
    }
}
posted @ 2017-07-23 23:38  NTR-NightRaven  阅读(513)  评论(0编辑  收藏  举报