作者:Dong |可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明
网址:http://dongxicheng.org/structure/treap/

1. 概述

同splay tree一样,treap也是一个平衡二叉树,不过Treap会记录一个额外的数据,即优先级。Treap在以关键码构成二叉搜索树的同时,还按优先级来满足堆的性质。因而,Treap=tree+heap。这里需要注意的是,Treap并不是二叉堆,二叉堆必须是完全二叉树,而Treap可以并不一定是。

2. Treap基本操作

为了使Treap 中的节点同时满足BST性质和最小堆性质,不可避免地要对其结构进行调整,调整方式被称为旋转。在维护Treap 的过程中,只有两种旋转,分别是左旋转(简称左旋)和右旋转(简称右旋)。

左旋一个子树,会把它的根节点旋转到根的左子树位置,同时根节点的右子节点成为子树的根;右旋一个子树,会把它的根节点旋转到根的右子树位置,同时根节点的左子节点成为子树的根。

struct Treap_Node{Treap_Node *left,*right; //节点的左右子树的指针int value,fix; //节点的值和优先级};void Treap_Left_Rotate(Treap_Node *&a) //左旋 节点指针一定要传递引用{Treap_Node *b=a->right;a->right=b->left;b->left=a;a=b;}void Treap_Right_Rotate(Treap_Node *&a) //右旋 节点指针一定要传递引用{Treap_Node *b=a->left;a->left=b->right;b->right=a;a=b;}

3. Treap的操作

同其他树形结构一样,treap的基本操作有:查找,插入,删除等。

3.1    查找

同其他二叉树一样,treap的查找过程就是二分查找的过程,复杂度为O(lg n)。

3.2    插入

在Treap 中插入元素,与在BST 中插入方法相似。首先找到合适的插入位置,然后建立新的节点,存储元素。但是要注意新的节点会有一个优先级属性,该值可能会破坏堆序,因此我们要根据需要进行恰当的旋转。具体方法如下:

1. 从根节点开始插入;

2. 如果要插入的值小于等于当前节点的值,在当前节点的左子树中插入,插入后如果左子节点的优先级小于当前节点的优先级,对当前节点进行右旋;

3. 如果要插入的值大于当前节点的值,在当前节点的右子树中插入,插入后如果右子节点的优先级小于当前节点的优先级,对当前节点进行左旋;

4. 如果当前节点为空节点,在此建立新的节点,该节点的值为要插入的值,左右子树为空,插入成功。

Treap_Node *root;void Treap_Insert(Treap_Node *&P,int value) //节点指针一定要传递引用{if (!P) //找到位置,建立节点{P=new Treap_Node;P->value=value;P->fix=rand();//生成随机的修正值}else if (value <= P->value){Treap_Insert(P->left,r);if (P->left->fix < P->fix)Treap_Right_Rotate(P);//左子节点修正值小于当前节点修正值,右旋当前节点}else{Treap_Insert(P->right,r);if (P->right->fix < P->fix)Treap_Left_Rotate(P);//右子节点修正值小于当前节点修正值,左旋当前节点}}

3.3   删除

与BST 一样,在Treap 中删除元素要考虑多种情况。我们可以按照在BST 中删除元素同样的方法来删除Treap 中的元素,即用它的后继(或前驱)节点的值代替它,然后删除它的后继(或前驱)节点。

上述方法期望时间复杂度为O(logN),但是这种方法并没有充分利用Treap 已有的随机性质,而是重新得随机选取代替节点。我们给出一种更为通用的删除方法,这种方法是基于旋转调整的。首先要在Treap 树中找到待删除节点的位置,然后分情况讨论:

情况一,该节点为叶节点或链节点,则该节点是可以直接删除的节点。若该节点有非空子节点,用非空子节点代替该节点的,否则用空节点代替该节点,然后删除该节点。

情况二,该节点有两个非空子节点。我们的策略是通过旋转,使该节点变为可以直接删除的节点。如果该节点的左子节点的优先级小于右子节点的优先级,右旋该节点,使该节点降为右子树的根节点,然后访问右子树的根节点,继续讨论;反之,左旋该节点,使该节点降为左子树的根节点,然后访问左子树的根节点,这样继续下去,直到变成可以直接删除的节点。

BST_Node *root;
void Treap_Delete(Treap_Node *&P, int *value) //节点指针要传递引用
{
   if (value==P->value) //找到要删除的节点 对其删除
   {
     if (!P->right || !P->left) //情况一,该节点可以直接被删除
     {
       Treap_Node *t=P;
       if (!P->right)
         P=P->left; //用左子节点代替它
       else
         P=P->right; //用右子节点代替它
       delete t; //删除该节点
     }
     else //情况二
     {
       if (P->left->fix < P->right->fix) //左子节点修正值较小,右旋
       {
         Treap_Right_Rotate(P);
         Treap_Delete(P->right,r);
       }
       else //左子节点修正值较小,左旋
       {
         Treap_Left_Rotate(P);
          Treap_Delete(P->left,r);
       }
     }
   }
   else if (value < P->value)
     Treap_Delete(P->left,r); //在左子树查找要删除的节点
   else
     Treap_Delete(P->right,r); //在右子树查找要删除的节点
}

4. Treap应用

Treap可以解决splay tree可以解决的所有问题,具体参见另一篇博文:《数据结构之伸展树》

可以这样定义结构体:

struct Treap_Node{Treap_Node *left,*right; //节点的左右子树的指针int value,fix,weight,size; //节点的值,优先级,重复计数(记录相同节点个数,节省空间),子树大小inline int lsize(){ return left ?left->size ?0; } //返回左子树的节点个数inline int rsize(){ return right?right->size?0; } //返回右子树的节点个数};

5. 总结

Treap 作为一种简洁高效的有序数据结构,在计算机科学和技术应用中有着重要的地位。它可以用来实现集合、多重集合、字典等容器型数据结构,也可以用来设计动态统计数据结构。

6. 参考资料

(1)Treap:http://www.nocow.cn/index.php/Treap

(2)随机平衡二叉查找树Treap 的分析与应用:http://www.byvoid.com/blog/wp-content/uploads/2010/12/treap-analysis-and-application.pdf

Treap tree相关推荐

  1. 【数据结构】平衡树 - treap

    treap = tree + heap 树堆(treap:让BST尽量随机) 动态维护一个有序序列 对于一个大根堆: 最大值:一直往右走 最小值:一直往左走 treap实现操作 set实现 ①插入 i ...

  2. BZOJ 3224: Tyvj 1728 普通平衡树 treap

    3224: Tyvj 1728 普通平衡树 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...

  3. 数据结构之Treap

    1. 概述 同splay tree一样,treap也是一个平衡二叉树,不过Treap会记录一个额外的数据,即优先级.Treap在以关键码构成二叉搜索树的同时,还按优先级来满足堆的性质.因而,Treap ...

  4. 带旋treap概念及模板,带例题:普通平衡树

    带旋Treap 二叉查找树BST(Binary Search Tree)定义 Treap定义 模板合集(均为O(logn)O(logn)O(logn)) push_up模板 旋转模板 插入模板 删除模 ...

  5. Treap树(堆树)

    描述 Treap=Tree+Heap(堆树). Treap 是一棵二叉搜索树 树的每个节点存储左指针和右指针,以及一个优先级,这个优先级是建树的时候随机制定的. 树的节点优先级满足堆序性质:任何节点的 ...

  6. Treap图文详解、效率分析与拓展应用——清华大学计算机系 郭家宝

    先给出我自己的一份Treap的代码--传送门 一.什么是 Treap Treap=Tree+HeapTreap=Tree+HeapTreap=Tree+Heap TreapTreapTreap是一种平 ...

  7. 查找——图文翔解Treap(树堆)

    之前我们讲到二叉搜索树,从二叉搜索树到2-3树到红黑树到B-树. 二叉搜索树的主要问题就是其结构与数据相关,树的深度可能会很大,Treap树就是一种解决二叉搜索树可能深度过大的另一种数据结构. Tre ...

  8. Treap平衡树学习笔记

    Treap平衡树学习笔记 放在前面的话 与信息学竞赛告别9个月后,中考终于结束,我终于复出了... 结果一回来就学数据结构,学得我有点懵... 本文写了两个多星期... 尽管学习Treap感到万分痛苦 ...

  9. 史上最强图解Treap总结, 不是浅谈!

    大家都很强, 可与之共勉. Treap = Tree + Heap. 树堆,在数据结构中也称Treap,是指有一个随机附加域满足堆的性质的二叉搜索树,其结构相当于以随机数据插入的二叉搜索树.其基本操作 ...

最新文章

  1. 路印协议受邀参加澳洲新南威尔士政府孵化器Haymarket HQ分享论坛
  2. 使用javascript开发2048
  3. JavaScript之事件冒泡和事件捕获详细介绍
  4. SQL Server的链接服务器技术小结
  5. css 渐变色_如何设置渐变色的单元格值?
  6. pivot 附近有语法错误,您可能需要将当前数据库的兼容级别设置为更高的值。...
  7. RabbitMQ消息队列(七):适用于云计算集群的远程调用(RPC)
  8. 关于javascript中私有作用域的预解释
  9. jqgrid学习(三)
  10. junit junit_穿越JUnit流
  11. IDEA——Git 的设置与使用
  12. SpringBoot项目的 log4j漏洞解决—JeecgBoot
  13. Ubuntu-18.04.1安装QQ
  14. 在SQL Server中导入和使用CSV文件
  15. Microsoft Visual Studio 2012 产品密匙
  16. 【爱思考】CISP考试试题介绍(其中一部分)
  17. 成都最最最牛逼的 IT 公司全在这了
  18. NLP标注工具:【免费:doccano、标注精灵、brat、YEDDA、DeepDive、rasa-nlu-trainer】【收费:Prodigy】
  19. 原生js绑定事件的三种方法
  20. 没什么,国内做任何大项目,不外乎人情.技术是次要的

热门文章

  1. 算法竞赛基础训练题_填空题
  2. 【NOIP2013】积木大赛(差分数组,贪心模拟)
  3. zk - zookeeper实现分布式锁代码
  4. ipmitool介绍_linux--ipmitool 详解
  5. 前端学习日记(八):css中字体、列表、鼠标形状、显示与隐藏、溢出处理、盒子模型的简单应用
  6. 树莓派4B供电不足导致相机采图死机输入死机的解决
  7. oledbdatareader和OleDbDataAdapter之间的区别
  8. u3d011 秘密行动_学习记录
  9. 关于JS出现的Cannot read property 'val' of null错误
  10. 不让三星、LG独美,夏普在IFA 2012推出新型IGZO屏幕