- 树堆的定义
树堆,在数据结构中也称Treap,是指有一个随机附加域满足堆的性质的二叉搜索树,其结构相当于以随机数据插入的二叉搜索树。其基本操作的期望时间复杂度为O(logn)。相对于其他的平衡二叉搜索树,Treap的特点是实现简单,且能基本实现随机平衡的结构。树堆是一种自平衡二叉查找树
树堆(Treap)是一棵 二叉排序树 ,它的左子树和右子树分别是一个Treap,和一般的二叉排序树不同的是,Treap纪录一个额外的数据,就是优先级。
- 树堆的性质
一种实现相对容易的平衡二叉树,称为Treap=Tree+Heap
①每个结点有两个键值(key , priority)
②Treap关于key的二叉排序树
③Treap关于priority是堆,但注意,Treap和二叉堆有一点不同,二叉堆必须是完全二叉树,而Treap不一定是
当key和priority确定时,Treap唯一
树堆的性质,就解释了为什么叫做“Treap”,因为它同时具有二叉查找树和对的性质
令Treap同时满足树堆性质的方法
⑴先令其满足二叉排序树性质
⑵通过左旋或者优选,使其同时满足堆的性质
- 树堆的操作
- 插入操作
给节点随机分配一个优先级,先和二叉排序树的插入一样,先把要插入的点插入到一个叶子上,然后跟维护堆一样,如果当前节点的优先级比根大就旋转,如果当前节点是根的左儿子就右旋如果当前节点是根的右儿子就左旋。
我们如果把插入写成递归形式的话,只需要在递归调用完成后判断是否满足堆性质,如果不满足就旋转
由于是旋转的二叉排序树,最多进行h次(h是树的高度),插入的复杂度是log( n )的,在期望情况下,所以它的期望复杂度是 O( log( N ) );
插入算法:
①给要插入的结点分配一个优先级
②如同二叉查找树的插入,把结点作为叶子插入
③维护堆的性质,若当前结点的优先级比双亲结点优先级小就旋转:
如果当前结点是根的左子树就右旋
如果当前结点是根的右子树就左旋
假设要插入的数为1,2,3,4,5,6
通过随机函数得到优先级:10,22,5,80,37,45
- 删除操作
有了旋转的操作之后,Treap的删除比二叉查找树还要简单。因为Treap满足堆性质。所以我们只需要
①把要删除的结点旋转为单孩子结点或叶子结点
②直接删除
具体方法就是每次找到优先级最小的儿子,向与其相反的方向旋转,(左子树优先级小,右旋)直接到那个结点被旋转成单孩子结点或叶子结点,然后直接删除。
删除结点的具体操作:
第一种:将结点下旋,左子树优先级9比右子树优先级11小,右旋。知道该结点不是双孩子的情况,知道旋转为单孩子结点
删除步骤:
1.把要删除的结点与直接后继或直接前驱交换;
2.直接删除直接后继或直接前驱
查找直接后继或直接前驱的复杂度为O(h)
第二种:跟普通的二叉查找树一样,找到“右子树”的最左结点15(直接后继),拷贝元素的值,但不拷贝元素的优先级,然后在右子树中删除“结点15”即可