Treap树

来源:互联网 发布:php开发游戏 编辑:程序博客网 时间:2024/05/16 16:07

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;}
原创粉丝点击