Treap(数堆)

定义

数堆名字取了Tree和Heap各一半,即Treap,是二叉搜索树和堆合并构成的数据结构。而堆和二叉搜索树的性质是有冲突的,二叉搜索树满足左子树<根节点<右子树,而堆是满足根节点小于等于(或大于等于)左右子树。因此在Treap的数据结构中,并不是以单一的键值作为节点的数据域。Treap每个节点的数据域包含2个值,key和weight。key值,和原来的二叉搜索树一样,满足左子树<根节点<右子树weight值在Treap中满足堆的性质,根节点的weight值小于等于(或大于等于)左右儿子节点。

示例Treap:


Treap

代码实现为:

struct Node
{
    int key;
    int weight;
    Node * lchild;
    Node * rchild;
    Node * father;
}Node;

旋转操作

Treap大部分操作和二叉搜索树是一样的,区别是插入操作时weight值可能会不满足堆的性质,这时需要进行旋转操作
示例:

旋转之前

右儿子节点是新插入的,并不满足堆的性质,所以要对其进行调整,假设这个Treap满足小根堆的性质,则调整结果为

旋转之后

这样最小的weight值就位于根节点处。这个操作叫做旋转。

  • 将右儿子调整至根部的旋转叫做左旋
  • 将左儿子调整至根部的旋转叫做右旋

左旋操作

左旋操作

操作过程:

  1. 获取根节点A的右儿子节点B
  1. 将节点B的父亲节点信息更新为f,并更新节点f的子节点信息为B
  2. 将节点A的右儿子信息更新为节点B的左儿子D,同时将节点D的父亲节点信息更新为A
  3. 将节点B的左儿子信息更改为节点A,同时将节点A的父亲节点信息更改为B

代码实现为

void LeftRotate( Node &*A )
{
    // step1
    Node *B=A->rchild;
    // step2
    B->father=A->father;
    if( A->father->lchild == A )
        B->father->lchild=B;
    else
        B->father->rchild=B;
    // step3
    if( B->lchild!=NULL )
    {
        A->rchild=B->lchild;
        B->lchild->father=A;
    }
    // step4
    A->father=B;
    B->lchild=A;
}

右旋操作

右旋操作

其操作是左旋的镜像

  1. 获取根节点A的左儿子节点B
  1. 将节点B的父亲节点信息更新为f,并更新节点f的子节点信息为B
  2. 将节点A的左儿子信息更新为节点B的右儿子D,同时将节点D的父亲节点信息更新为A
  3. 将节点B的右儿子信息更改为节点A,同时将节点A的父亲节点信息更改为B

代码实现为

void RightRotate( Node &*A )
{
    // step1
    Node *B=A->lchild;
    // step2
    B->father=A->father;
    if( A->father->lchild == A )
        B->father->lchild=B;
    else
        B->father->rchild=B;
    // step3
    if( B->rchild!=NULL )
    {
        A->lchild=B->rchild;
        B->rchild->father=A;
    }
    // step4
    A->father=B;
    B->lchild=A;
}

总结

数堆的优势为:对于一般的二叉搜索树,在某些特殊情况下根据输入数据来建树有可能退化为一条链,比如一个依次增大的数列。而如果一棵二叉排序树的节点是按照随机顺序插入,得到的二叉排序树大多数情况下是平衡的,其期望高度是O(logn)。因此Treap利用weight值作为随机因子来调整二叉树的形状,使得在大部分情况下比直接通过数据建立的二叉树要平衡。
每一次查找的期望复杂度也会降低,总体的速度也就得到了提高。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 树的概述 树是一种非常常用的数据结构,树与前面介绍的线性表,栈,队列等线性结构不同,树是一种非线性结构 1.树的定...
    Jack921阅读 9,973评论 1 31
  • 1 序 2016年6月25日夜,帝都,天下着大雨,拖着行李箱和同学在校门口照了最后一张合照,搬离寝室打车去了提前租...
    RichardJieChen阅读 10,637评论 0 12
  • 第一章 绪论 什么是数据结构? 数据结构的定义:数据结构是相互之间存在一种或多种特定关系的数据元素的集合。 第二章...
    SeanCheney阅读 11,120评论 0 19
  • ___as7阅读 3,184评论 0 0
  • 高中那会儿学校老是爱向衡水中学学习,每日课前宣誓便是不少奇葩制度中的一项。 每日要选出一位领誓人,领誓人完成一天的...
    檐下灰阅读 2,425评论 0 1

友情链接更多精彩内容