Treap树

Treap树的节点具有优先级,优先级是在建立节点时随机指定的。Treap树是节点优先级满足堆序的二叉查找树:任意节点的优先级至少和它的父节点的优先级一样大。根节点优先级最低。nullNode节点优先级为无穷。

头文件

#include <climits>
#include "UniformRandom.hpp"
template <typename Comparable>
class Treap
{
public:
    Treap()
    {
        nullNode=new TreapNode;
        nullNode->left=nullNode->right=nullNode;
        nullNode->priority=INT_MAX;

        root=nullNode;


    }

    Treap(const Treap & rhs);
    Treap(Treap && rhs);
    ~Treap();
    Treap & operator=(const Treap & rhs);
    Treap & operator=(Treap && rhs);

    void insert(const Comparable & x)
    {
        insert(x,root);
    }

    void remove(const Comparable & x)
    {
        remove(x,root);
    }
private:
    struct TreapNode
    {
        Comparable  element;
        TreapNode   *left;
        TreapNode   *right;
        int         priority;

        TreapNode(const Comparable & ele=Comparable{},
                  TreapNode * lt=nullptr,TreapNode * rt=nullptr,
                  int prior=INT_MAX):element(ele),left(lt),right(rt),priority(prior){}

        TreapNode(Comparable && ele=Comparable{},
                  TreapNode * lt=nullptr,TreapNode * rt=nullptr,
                  int prior=INT_MAX):element(ele),left(lt),right(rt),priority(prior){}
    };

    void insert(const Comparable & x,TreapNode * & t);
    void remove(const Comparable & x,TreapNode * & t);

    TreapNode *nullNode;
    TreapNode *root;
    UniformRandom randomNums;
    void rotateWithLeftChild(TreapNode * & t);
    void rotateWithRightChild(TreapNode * & t);
};

生成随机数的头文件

#include <chrono>
#include <random>
#include <functional>
using namespace std;

static inline int currentTimeSeconds()
{
    auto now=chrono::high_resolution_clock::now().time_since_epoch();
    return (chrono::duration_cast<chrono::seconds>(now)).count();
}

class UniformRandom
{
public:
    UniformRandom(int seed=currentTimeSeconds()):generator(seed){}
    //生成伪随机int
    int nextInt()
    {
        static uniform_int_distribution<unsigned int> distribution;
        return distribution(generator);
    }
    //生成[0,high)之间的伪随机int
    int nextInt(int high)
    {
        return nextInt(0,high-1);
    }
    //生成[low,high]之间的伪随机int
    int nextInt(int low,int high)
    {
        uniform_int_distribution<int> distribution(low,high);
        return distribution(generator);
    }
    //生成[0,1)之间的伪随机double
    double nextDouble()
    {
        static uniform_real_distribution<double> distribution(0,1);
        return distribution(generator);
    }

private:
    mt19937 generator;
};

cpp文件

#include "Treap.hpp"

template<typename Comparable>
void Treap<Comparable>::insert(const Comparable & x,TreapNode* & t)
{
    if(t==nullNode)
        t=new TreapNode{x,nullNode,nullNode,randomNums.nextInt()};
    else if(x<t->element)
    {
        insert(x, t->left);
        if(t->left->priority<t->priority)
            rotateWithLeftChild(t);
    }
    else if(t->element<x)
    {
        insert(x, t->right);
        if(t->right->priority<t->priority)
            rotateWithRightChild(t);
    }
}

template<typename Comparable>
void Treap<Comparable>::remove(const Comparable & x, TreapNode * & t)
{
    if(t!=nullNode)
    {
        if(x==t->element)
        {
           //堆序操作,从两个儿子中选取优先级低的替代它
            if(t->left->priority<t->right->priority)
                rotateWithLeftChild(t);
            else
                rotateWithRightChild(t);

            //t为旋转后新的子根
            if(t!=nullNode)
                remove(x, t);
            else
            {
                delete t->left;//变成树叶后还要与右nullNode旋转,因此变成了nullNode的左儿子
                t->left=nullNode;
            }

        }
        else if(x<t->element)
        {
            remove(x, t->left);
        }
        else
        {
            remove(x, t->right);
        }
    }
}

template <typename Comparable>
void Treap<Comparable>::rotateWithLeftChild(TreapNode * & k2)
{
    TreapNode * k1=k2->left;
    k2->left=k1->right;
    k1->right=k2;
    k2=k1;


}

template <typename Comparable>
void Treap<Comparable>::rotateWithRightChild(TreapNode * & k1)
{
    TreapNode * k2=k1->right;
    k1->right=k2->left;
    k2->left=k1;
    k1=k2;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值