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;
}