一棵treap是一棵修改了结点顺序的二叉查找树,如图,显示一个例子,通常树内的每个结点x都有一个关键字值key[x],另外,还要为结点分配priority[x],它是一个独立选取的随机数。
假设所有的优先级是不同的,所有的关键字也是不同的。treap的结点排列成让关键字遵循二叉查找树性质,并且优先级遵循最小堆顺序性质:
1.如果v是u的左孩子,则key[v] < key[u].
2.如果v是u的右孩子,则key[v] > key[u].
3.如果v是u的孩子,则priority[u] > priority[u].
这两个性质的结合就是为什么这种树被称为“treap”的原因,因为它同时具有二叉查找树和堆的特征。
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
struct TNode
{
int priority;
int value;
TNode * left;
TNode * right;
TNode *parent;
TNode()
{
priority = rand();
left = NULL;
right = NULL;
parent = NULL;
}
};
struct Tree
{
TNode * root;
Tree()
{
root = NULL;
}
};
void treap_insert(int value,Tree&t);
void treap_insert_fixup(Tree&t,TNode *x);
void left_rotate(Tree &t,TNode *x);
void right_rotate(Tree&t,TNode*x);
void printTT(Tree &t);
void print(TNode *x);
int main ()
{
//srand(time(NULL));
Tree t;
for (int i = 1;i < 14;i ++)
{
treap_insert(i,t);
}
printTT(t);
}
void treap_insert(int value,Tree&t)
{
TNode * p = new TNode();
p->value = value;
TNode * r = t.root;
TNode * s = NULL;
if (NULL == t.root)
{
t.root = p;
return ;
}
else
{
while (r != NULL)
{
s = r;
if (r->value < value)
{
r = r->right;
}
else
{
r = r->left;
}
}
if (s->value < value)
{
s->right = p;
}
else
{
s->left = p;
}
p->parent = s;
treap_insert_fixup(t,p);
}
}
void treap_insert_fixup(Tree&t,TNode *x)
{
TNode * y = NULL;
while (x != NULL && x->parent != NULL)
{
y = x->parent;
if (x->priority > y->priority)
{
break;
}
else
{
if(x == y->left)
{
right_rotate(t,y);
}
else
{
left_rotate(t,y);
}
}
}
}
void left_rotate(Tree&t,TNode*x)
{
TNode * y = x->right;
if (t.root == x)
{
t.root = y;
}
else if (x == x->parent->left)
{
x->parent->left = y;
}
else
{
x->parent->right = y;
}
y->parent = x->parent;
x->right = y->left;
if(x->right)
{
x->right->parent = x;
}
y->left = x;
x->parent = y;
}
void right_rotate(Tree&t,TNode*x)
{
TNode * y = x->left;
if (t.root == x)
{
t.root = y;
}
else if (x == x->parent->left)
{
x->parent->left = y;
}
else
{
x->parent->right = y;
}
y->parent = x->parent;
x->left = y->right;
if(x->left)
{
x->left->parent = x;
}
y->right = x;
x->parent = y;
}
void printTT(Tree&t)
{
cout <<"************" <<endl;
print(t.root);
cout <<"************" <<endl;
}
void print(TNode*x)
{
if (NULL != x)
{
cout << x->value << " " << x->priority<<endl;
print(x->left);
print(x->right);
}
}