zoukankan      html  css  js  c++  java
  • 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);
        }
    }
    
  • 相关阅读:
    java线程
    面向切面编程
    控制反转IOC与依赖注入DI
    phpexecel 导入导出,格式
    PHPExcel设置数据格式的几种方法
    九度oj 题目1416:猴子吃坚果
    九度oj 题目1397:查找数段
    poj 1065 Wooden Sticks
    poj 3181 Dollar Dayz
    poj 1742 Coins
  • 原文地址:https://www.cnblogs.com/NightRaven/p/9333250.html
Copyright © 2011-2022 走看看