随机二叉搜索树 Treap

   (当个日记记录Treap这一结构,详细参见http://www.nocow.cn/index.php/Treap, 在这里我着重讲一下旋转)

    Treap,它其它就是一个二叉查找树(BST)+堆(HEAP). 它的数据有两个:关键值(key),优先级(fix).

    用struct表示Treap的结点的结构如下:

   struct node

   {

        datatype key;

         int  fix;

         node * left;

         node * right;

  }

   Treap的key值满足BST的性质:即任一个Treap的结点x,若y是x的左子树,则y.key<=x.key,若y为x的右子树,则y.key>=x.key.

   同时Treap的fix满足Heap的性质(在这里以最大堆为例):即任一个Treap的结点x,若y为x的左子树或右子树,则x.fix>=y.fix.

   如下图所示则为Treap

Treap

       Treap的作用:它的作用同BST一样,引入优先级这一概念是为了防止BST退化成一链表(BST的建立依籁于结点的插入顺序,当有序的插入时,则BST为一链表,其它查找插入的复杂度o(n)),当然我们完全可以随机的插入结点,但是有时候我们事先并不知道所有结点,在这种情况下我们可以采用Treap,即当需要插入的一个新的key值,我们可以随机的生成一个优先级(fix),然后通过fix约束Treap,从而达到随机生成BST的目的.

       为了插入和删除之后仍然保持Treap的两个性质,在这里Treap提供了两种旋转的操作,右旋和左旋

        (1)结点右旋:node x,y=x->left; 先将y的右子树作为x的左子树,然后将x作为y的右子树, 最后将y作为x原父结点的子树(x为左子树,此时y仍然为左子树,x为右子树,y也为右子树)如下图所示.

         右旋

        (2)结点左旋:同右旋刚好相反.node x,y=x->right; 先将y的左子树作为x的右子树,然后将x作为y的左子树, 最后将y作为x原父结点的子树(x为左子树,此时y仍然为左子树,x为右子树,y也为右子树)如下图所示.

       左旋

    

由上可见,旋转操作之后仍然满足BST的特性,但是改变Heap的性质.

           插入操作:有了旋转操作后,插入变得十分简单.它只需要将结点(key,fix)BST插入到Treap,此时若不满足Heap的性质,若结点x的左子树的fix大于xfix,则只需要左旋,若结点y的右子树的fix值大于xfix,则左旋.直至满足Heap的性质.

          删除操作:只需要将删除的结点旋转至叶结点,直接插除即可.

          对于其它的查找,后继,最小值等操作均同BST一样,在这里便不再详述.附有C++ Treap实现.

         

 

             

  

  

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值