Treap还是比较好写的,但是要加入动态顺序统计和parent指针就稍微有些麻烦了。一个重要的经验是采用哨兵(本例中是nullnode),这样会带来很大方便的。
//结点类型
typedef struct node

...{
int key, pri, size; //关键字,权值,统计量
node *left, *right, *parent; //左孩子、右孩子、父结点
//初始化一个空结点
node()
: pri(INT_MAX), left(NULL), right(NULL), parent(NULL), size(1)

...{}
//用制定的参数初始化
node(int k, node *l, node *r, node *p, int pr)
: key(k), left(l), right(r), parent(p), pri(pr), size(1)

...{}
}*nodeptr;

//Treap类
class Treap

...{
private:
nodeptr root;
nodeptr nullnode;
//左旋
inline void rotate_left(nodeptr &t)

...{
nodeptr p = t -> right;
p -> parent = t -> parent;
t -> right = p -> left;
p -> left -> parent = t;
p -> left = t;
t -> parent = p;
p -> size = t -> size;
t -> size = t -> left -> size + t -> right -> size + 1;
t = p;
}
//右旋
inline void rotate_right(nodeptr &t)

...{
nodeptr p = t -> left;
p -> parent = t -> parent;
t -> left = p -> right;
p -> right -> parent = t;
p -> right = t;
t -> parent = p;
p -> size = t -> size;
t -> size = t -> left -> size + t -> right -> size + 1;
t = p;
}
//向t处插入值为x的结点
inline void insert(int x, nodeptr &t, nodeptr pi)

...{
if (t == nullnode)

...{
srand(static_cast<unsigned long>(time(NULL)));
//下面这句注意:
//VC 2005下,应为rand()*rand()
//g++下,应为rand()
t = new node(x, nullnode, nullnode, pi, rand());
//向上更新
nodeptr tmp = t;
while (tmp -> parent != nullnode)

...{
tmp = tmp -> parent;
tmp -> size++;
}
return;
}
if (x < t -> key)

...{
insert(x, t -> left, t);
if (t -> left -> pri < t -> pri)
rotate_right(t);
}
else

...{
insert(x, t -> right, t);
if (t -> right -> pri < t -> pri)
rotate_left(t);
}
}
inline void remove(int x, nodeptr &t)

...{
if (t == nullnode)
return;
if (x < t -> key)
remove(x, t -> left);
else if (x > t -> key)
remove(x, t -> right);
else

...{
//以下用来处理有相同key的结点
bool skip = false;
if (t -> left != nullnode && t -> key == t -> left -> key)

...{
remove (x, t -> left);
skip = true;
}
else if (t -> right != nullnode && t -> key == t -> right -> key)

...{
remove (x, t -> right);
skip = true;
}
//以下是正常的删除准备
else if (t -> left -> pri < t -> right -> pri)
rotate_right(t);
else
rotate_left(t);
//没有相同结点时直接删除
if (!skip)

...{
if (t != nullnode)
remove(x, t);
else

...{
delete t -> left;
t -> left = nullnode;
}
}
}
}
inline void makeEmpty(nodeptr &t)

...{
if (t != nullnode)

...{
makeEmpty (t -> left);
makeEmpty (t -> right);
delete t;
}
t = nullnode;
}
inline void travel(nodeptr &t)

...{
if (t != nullnode)

...{
travel(t -> left);
//请改为相关操作
cout << t -> key << endl;
travel (t -> right);
}
}
//返回以current为根的树最小值
inline nodeptr min(nodeptr current)

...{
while (current -> left != nullnode)
current = current->left;
return current;
}
//返回以current为根的树最大值
inline nodeptr max(nodeptr current)

...{
while (current -> right != nullnode)
current = current -> right;
return current;
}
//返回以x为根,第i大的元素的值
inline nodeptr select(nodeptr x, int i)

...{
int r = x -> left -> size + 1;
if (i == r)
return x;
else if (i < r)
return select(x -> left, i);
else
return select(x -> right, i - r);
}
public:
Treap()

...{
nullnode = new node; //哨兵结点
nullnode -> left = nullnode -> right = nullnode -> parent = nullnode;
nullnode -> size = 0;
root = nullnode; //根为空
}
~Treap()

...{
makeEmpty();
delete nullnode;
}
//返回最小元素
inline nodeptr min()

...{
if (isEmpty())
return NULL;
return min(root);
}
//返回最大元素
inline nodeptr max()

...{
if (isEmpty())
return NULL;
return max(root);
}
//返回是否空
inline bool isEmpty()

...{
return (root == nullnode);
}
//插入x
inline void insert(int x)

...{
insert(x, root, nullnode);
}
//删除值为x的结点
inline void remove(int x)

...{
remove(x, root);
}
//清空
inline void makeEmpty()

...{
makeEmpty(root);
}
//遍历
inline void travel()

...{
if (!isEmpty())
travel(root);
}
//查找
//如果存在,返回指向这个结点的指针,否则返回NULL
inline nodeptr find(int x)

...{
nodeptr current = root;
nullnode -> key = x;
while(1)

...{
if (x < current -> key)
current = current -> left;
else if (x > current -> key)
current = current -> right;
else if (current != nullnode)
return current;
else
return NULL;
}
}
//返回后继
inline nodeptr succ(nodeptr current)

...{
if (current == NULL)
return NULL;
if (current -> right != nullnode)
return min(current -> right);
nodeptr y = current -> parent;
while (y != nullnode && current == y -> right)

...{
current = y;
y = y -> parent;
}
return y;
}
inline nodeptr succ(int x)

...{
return succ(find(x));
}
//返回前驱
inline nodeptr pred(nodeptr current)

...{
if (current == NULL)
return NULL;
if (current -> left != nullnode)
return max(current -> left);
nodeptr y = current -> parent;
while (y != nullnode && current == y -> left)

...{
current = y;
y = y -> parent;
}
return y;
}
inline nodeptr pred(int x)

...{
return pred(find(x));
}
inline nodeptr select(int i)

...{
return select(root, i);
}
//返回x在树中的位置
inline int rank(nodeptr x)

...{
int r = x -> left -> size + 1;
nodeptr y = x;
while (y != root)

...{
if (y == y -> parent -> right)
r += y -> parent -> left -> size +1;
y = y -> parent;
}
return r;
}
};