Treap树堆,是有一个随机附加域满足堆的性质的二叉搜索树,其结构相当于以随机数据插入的二叉搜索树。其基本操作的期望时间复杂度为 O(logn) O ( l o g n ) 。相对于其他的平衡二叉搜索树,Treap的特点是实现简单,且能基本实现随机平衡的结构。
Treap=Tree+Heap。Treap本身是一棵二叉搜索树,它的左子树和右子树也分别是一个Treap。每一个节点除了保持了key,孩子指针之外,和一般的二叉搜索树不同的是,Treap额外记录了优先级,一般是不变的[0,1]的值。Treap在以关键码构成二叉搜索树的同时,优先值还满足堆的性质。Treap维护堆性质的方法用到了旋转,只需要两种旋转,编程复杂度比Splay要小一些。
插入
给节点随机分配一个优先级,先和二叉搜索树的插入一样,先把要插入的点插入到一个叶子上,然后跟维护堆一样,如果当前节点的优先级比根大就旋转,如果当前节点是根的左儿子就右旋如果当前节点是根的右儿子就左旋。
由于旋转是O(1)的,最多进行h次(h是树的高度),插入的复杂度是 O(h)的,在期望情况下 h=O(log n),所以它的期望复杂度是O(logn)。
def insert(self,k):
v = Insert k using standard binary tree insertion
# v is a leaf node
v.priority = random()
while v is not the root and v.priority < v.parent.priority
if v is a left child: rotate right(v.parent)
else:
rotate left(v.parent)
删除
因为Treap满足堆性质,所以只需要把要删除的节点旋转到叶节点上,然后直接删除就可以了。具体的方法就是每次找到优先级最大的儿子,向与其相反的方向旋转,直到那个节点被旋转到了叶节点,然后直接删除。
删除最多进行 O(h)次旋转,期望复杂度是O(logn)。
def delete(self,v):
while v is not a leaf:
if left(v) == None:
rotate left(v)
elif right(v) == None or v.left.priority > v.right.pri
rotate right(v)
else:
rotate left(v)
Delete the leaf node v
查找
和一般的二叉搜索树一样,但是由于Treap的随机化结构,Treap中查找的期望复杂度是O(logn)。