当前位置:  编程技术>c/c++/嵌入式

数据结构之Treap详解

    来源: 互联网  发布时间:2014-10-27

    本文导语:  1. 概述 同splay tree一样,treap也是一个平衡二叉树,不过Treap会记录一个额外的数据,即优先级。Treap在以关键码构成二叉搜索树的同时,还按优先级来满足堆的性质。因而,Treap=tree+heap。这里需要注意的是,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 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


    
 
 

您可能感兴趣的文章:

  • 数据结构之位图(bitmap)详解
  • 数据结构之堆详解
  • 数据结构课程设计- 解析最少换车次数的问题详解
  • 数据结构之AVL树详解
  • 数据结构课程设计-用栈实现表达式求值的方法详解
  • 数据结构之伸展树详解
  • 数据结构之红黑树详解
  • python实现bitmap数据结构详解
  • Python常见数据结构详解
  • 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
  • <<大话数据结构>>中冒泡排序算法改进
  • 请问:在用proc方式往数据库插入数据时,我能不能定义一个结构体,它与表的每一项对应,将结构体赋好值后,再只将这个结构体插入表中,这行不行啊?
  • 基于Key-Value的NOSQL数据库Redis的数据结构及常用相关命令介绍
  • 强人,linux下驱动相关数据结构和usb设备数据结构之间的功能分析
  • Oracle数据库(Oracle Database)体系结构及基本组成介绍
  • GNU汇编fill填充一个数据结构使得另一个数据结构全部清零
  • 数据结构:图(有向图,无向图),在Python中的表示和实现代码示例
  • 高手帮帮忙!vi中如何实现跳转到任意结构体或函数的声明处,包括系统库中声明的函数和数据结构?
  • mysql 命令大全及导入导出表结构或数据
  • 协议的设计一般采用结构体进行数据打包,在协议设计的结构体中能不能使用指针 ?
  • 通用数据结构库 GDSL
  • 如何把一个数组转化为一个数据结构,如ArrayList。
  • 多维数据结构 mdds
  • sem_t的数据结构是什么?
  • C数据结构库 liblfds
  • 一个新的JavaScript数据结构 stream.js
  • 数据结构和算法教程 OpenDSA
  • 数据结构
  • 请教各位,数据结构在工程中到底有什么应用呢
  • 放假了,想用java数据结构,请问大虾们该如何开始?
  • 数据结构库 libx1f4l2
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 请教:请问java中存放数据库中的记录,用什么数据结构?(hashtable?vector?还是别的?)
  • 看LINUX的内核要不要硬件、数据结构、算法、汇编
  • 请教JAVA中的数据结构
  • 常用数据结构库 sundial
  • 基于测试nginx数据结构的开源库 libngx
  • 数据结构算法库 DSAL
  • 哪里有《数据结构与算法分析(JAVA版)》的电子书下载,谢了:)
  • 那个大侠可以推荐一本关于java的数据结构和算法的书?  
  • 请大家推荐几本关于数据结构的书。
  • 一个可以自动排序、频繁增删的队列,采用哪种数据结构比较好?
  • “堆”和“栈”是有区别的数据结构,为什么很多书中都将它们放在一起使用呢?
  • 请问哪里有《数据结构与算法分析(JAVA版)》的电子书下载????
  • 求救!!!!关于(数据结构(java版)王国瑜/叶乃菁 编著)
  • 在头文件中,数据结构怎么写
  • 请问有关linux底层网络数据结构sk_buff相关知识
  • 请问哪里有比较全的Linux内核编程API和数据结构的文档?
  • 求救!!!!关于(数据结构(java版)王国瑜/叶乃菁 编著) iis7站长之家
  • 文本编辑器数据结构
  • 手把手教你Oracle数据库导出数据库结构到PowerDesigner
  • tslib数据结构的问题


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3