平衡树-Treap学习笔记


最近刚学了Treap

发现这种数据结构真的是——妙啊妙啊~~

咳咳。。。。

所以发一发博客,也是为了加深蒟蒻自己的理解

顺便帮助一下各位小伙伴们


切入正题


Treap的结构体

首先,Treap有两个定义

对于权值而言,它是二叉查找树

对于优先级而言,它是堆

由此,我们将Treap保存于结构体内

struct node
{
    node* ch[2];//左右孩子指针,0为左孩子,1,为右孩子
    int v,r;//v为该节点权值;r为优先级

    node(int v):v(v){ r=rand(); ch[0]=ch[1]=NULL;}
    //构造函数,用于初始化

    int cmp(int x) const{ if(x==v) return -1; return x<v ?0:1; }
    //这里的这个成员函数将在下面解释
};
node* rt=NULL;//这个是初始的根

旋转

既然平衡树

最重要的当然是旋转啦

先上一张baidu的图

结合图理解才透彻嘛

在这张图里面

我们要将中间那个圆节点旋转到根的位置

调用函数时的参数是图中最上面那个节点

(我这样说会不会有点不明白)

//d=0代表左旋;d=1代表右旋
void rotate(node* &p,int d)//结点记得加引用
{
    node* k=p->ch[d^1];
    p->ch[d^1]=k->ch[d];
    k->ch[d]=p;
    p=k;
}

其实看着图自己模拟一下就懂了

应该不用注释了吧


插入

既然Treap是二叉查找树

那么插入自然按照二叉查找树节点的性质啦

即每个结点的左孩子权值一定小于该节点,而右孩子反之

只要按照二叉查找树的插入方式递归寻找带插入位置就好

然而

Treap还是个堆啊

所以插入后还要判断优先级

之前我们初始化优先级r为随机rand()

从而保证了整个程序平均的运行效率

void ins(node* &p,int x)//x为带插入权值,结点记得加引用
{
    if(p==NULL){ p=new node(x); return; }
    //如果结点为NULL ,则找到了带插入结点,进行初始化
    int d=p->cmp(x);
    //这里运用了结构体中的cmp函数,用以确定x该插入左孩子还是右孩子
    //若x<该结点权值,cmp返回0,插入左孩子;反之亦然
    ins(p->ch[d],x);
    //递归插入
    if( p->ch[d]->r < p->r ) rotate(p,d^1);
    //*划重点*;插入后判断优先级以保证堆的性质
}

删除

寻找待删除结点依照二叉查找树的性质

这里主要讨论找到待删除结点后的操作

void del(node* &p,int x)//结点记得加引用
{
    if(p==NULL) return;//找到空结点就返回
    if(x==p->v)//找到待删除结点
    {
        if(p->ch[0]==NULL)
        {node *k=p; p=p->ch[1]; delete(k); return;}
        else if(p->ch[1]==NULL)
        {node *k=p; p=p->ch[0]; delete(k); return;}
        //如果这个结点只有一棵子树,就以该子树代替该节点

        else//如果两棵子树都不为空
        {
            //先把优先级较高的子树旋转到根
            //然后递归再另一颗子树中删除p
            int dd=p->ch[0]->r < p->ch[1]->r ?1 :0;
            rotate(p,dd);  del(p->ch[dd],x);
            return;
        }
    }
    //递归寻找待删除结点
    int d=p->cmp(x);
    del(p->ch[d],x);
}

Treap的基本操作就这些啦

蒟蒻的OI路还是漫漫无期

Treap-平衡树学习笔记的更多相关文章

  1. 平衡树学习笔记(2)-------Treap

    Treap 上一篇:平衡树学习笔记(1)-------简介 Treap是一个玄学的平衡树 为什么说它玄学呢? 还记得上一节说过每个平衡树都有自己的平衡方式吗? 没错,它平衡的方式是......rand ...

  2. 平衡树学习笔记(6)-------RBT

    RBT 上一篇:平衡树学习笔记(5)-------SBT RBT是...是一棵恐怖的树 有多恐怖? 平衡树中最快的♂ 不到200ms的优势,连权值线段树都无法匹敌 但是,通过大量百度,发现RBT的代码 ...

  3. 平衡树学习笔记(5)-------SBT

    SBT 上一篇:平衡树学习笔记(4)-------替罪羊树 所谓SBT,就是Size Balanced Tree 它的速度很快,完全碾爆Treap,Splay等平衡树,而且代码简洁易懂 尤其是插入节点 ...

  4. 平衡树学习笔记(3)-------Splay

    Splay 上一篇:平衡树学习笔记(2)-------Treap Splay是一个实用而且灵活性很强的平衡树 效率上也比较客观,但是一定要一次性写对 debug可能不是那么容易 Splay作为平衡树, ...

  5. BST,Splay平衡树学习笔记

    BST,Splay平衡树学习笔记 1.二叉查找树BST BST是一种二叉树形结构,其特点就在于:每一个非叶子结点的值都大于他的左子树中的任意一个值,并都小于他的右子树中的任意一个值. 2.BST的用处 ...

  6. [普通平衡树treap]【学习笔记】

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 9046  Solved: 3840[Submit][Sta ...

  7. 普通平衡树学习笔记之Splay算法

    前言 今天不容易有一天的自由学习时间,当然要用来"学习".在此记录一下今天学到的最基础的平衡树. 定义 平衡树是二叉搜索树和堆合并构成的数据结构,它是一 棵空树或它的左右两个子树的 ...

  8. 「FHQ Treap」学习笔记

    话说天下大事,就像fhq treap —— 分久必合,合久必分 简单讲一讲.非旋treap主要依靠分裂和合并来实现操作.(递归,不维护fa不维护cnt) 合并的前提是两棵树的权值满足一边的最大的比另一 ...

  9. Fhq Treap [FhqTreap 学习笔记]

    众所周知 Fhq Treap 是 fhq 神仙研究出来的平衡树- 具体实现 每个点实现一个 \(\text{rnd}\) 表示 rand 的值 为什么要 rand 呢 是为了保证树高为 \(\log ...

  10. 树堆(Treap)学习笔记 2020.8.12

    如果一棵二叉排序树的节点插入的顺序是随机的,那么这样建立的二叉排序树在大多数情况下是平衡的,可以证明,其高度期望值为 \(O( \log_2 n )\).即使存在一些极端情况,但是这种情况发生的概率很 ...

随机推荐

  1. DEDECMS 留言薄模块的使用方法

    一.留言薄的安装 留言薄的安装过程和其他插件一样,首先我们进入后台模块管理列表,点击其对应的"安装": 以上步骤,我们完成了留言薄插件的安装. 二.留言薄的卸载 留言薄的卸载,同样 ...

  2. QTP10破解方法及mgn-mqt82.exe下载

    经试验可以成功安装license,具体步骤如下:一.从HP官方网上下载QTP10.0并安装.二.安装成功后,在C:\Program Files\Common Files\Mercury Interac ...

  3. 服务器大量的fin_wait1 状态长时间存在原因分析-1

    上文描述了在出现大量fin-wait-1出现的原因,占用的内存等,这里讲一下如何处理这种情况. 首先,fin发送之后,有可能会丢弃,那么发送多少次这样的fin包呢?fin包的重传,也会采用退避方式,在 ...

  4. 2017-07-04(sudo wc sort)

    sudo 作用 root把本来只能超级用户执行的命令,赋予普通用户执行. 添加 运行visudo命令,在文件底部添加信息即可! sudo -l  查看用户可以运行的命令 use1  ALL=(ALL) ...

  5. python3 第三章 - 程序的基本结构

    1.编码 默认情况下,Python 3 源码文件以 UTF-8 编码,所有字符串都是 unicode 字符串. 当然你也可以为源码文件指定不同的编码: # -*- coding: cp-1252 -* ...

  6. JS与ajax遍历list

    示例: <script> <c:forEach var="yanan" items="${yananList}">            ...

  7. BSA Network Shell系列-runcmd/runscript命令

    runcmd和runscript ## 1 功能概述 runcmd/runscript:runcmd在一台或多台机器执行Network Shell命令(单个命令),而runscript执行的是脚本,二 ...

  8. Linux上常用软件安装和总结

    Linux总结: 以前只顾着撸码,Linux这些一般都是运维玩的,然后也没怎么折腾过,每次上线也都只是发布下,最多也就是启停服务器.最近闲来无事就玩了玩Linux,还挺好的. 这里做一个总结来结束Li ...

  9. Java与C/C++的区别

        首先应该清楚,Java是由C++发展而来的,它保留了c++的大部分内容,类似于c++,但句法更清晰,规模更小,更易学.它是在对多种程序设计语言进行了深入细致研究的基础上,据弃了其他语言的不足之 ...

  10. MyISAM 存储引擎的特点及优化方法

      MyISAM:   MyISAM 管理非事务表.是ISAM 的扩展格式.除了提供ISAM里所没有的索引的字段管理等的大量功能.MyISAM 还使用一种表格锁定的机制.来优化多个并发的读写操作.My ...