当前位置:天才代写 > tutorial > 大数据教程 > 数据结构之Treap

数据结构之Treap

2021-02-24 12:24 星期三 所属: 大数据教程 浏览:966

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

 

    关键字:

天才代写-代写联系方式