1.简介

首先要知道什么是二叉查找树。

这是一棵二叉树,每个节点最多有一个左儿子,一个右儿子。

它能支持查找功能。

具体来说,每个儿子有一个权值,保证一个节点的左儿子权值小于这个节点,右儿子权值大于这个节点。

显然可以证明,这个树的中序遍历就是树上的序列从小到大排序后的结果。

我们插入一个值,就类似二分,从根往下找,直到进入一个空节点,然后插入。

查询的时候,比如查询前驱后继第k大等等,本质上都是通过比较左右儿子的权值/子树大小等来决策。

由于和节点的加入顺序有关,

所以,二叉查找树这样可以被轻松卡成一条链,然后每次查询链的底部,就卡成一次O(n)的了。

我们发现,同一个正确的中序遍历下的二叉查找树可能形态有很多。

而如果一个二叉查找树是满的二叉查找树,那么树高就是logn的,查询复杂度O(logn)非常可观。

所以,我们能不能通过一些手段,使得这棵二叉查找树总是能保持在logn的树高左右呢?

如果树高能够保证在logn的话,那么就称这个树是平衡的。

这也是平衡树的由来。

所以,平衡树一种能维持树高为logn的二叉查找树。

属于高级数据结构。

2.平衡树分类(查询均摊logn)

treap:

tree+heap

维护中序遍历之外,每个点随机一个优先级。

根据优先级,进行左旋或者右旋。

splay

直接双旋保证复杂度。

可以证明。(我不会,记住就好了)

fhq 非旋转treap

SBT ??

RBT 红黑树,map的实现。

替罪羊树 ??

3.treap及操作

单旋,把儿子和父亲交换。

分为左旋右旋。

4.Splay及操作

没有优先值,但是采用双旋。

每次查询或者加入一个点,都把这个点旋转到根。

双旋的巧妙之处:

1.永远单旋是不够的。因为一条链转完还是一条链。

2.双旋一定程度上会把链缩短。

5.Splay的利用(每次最后都要splay到根)

单点操作:

①加入一个权值。从顶向下找,找到空节点加入。

②删除一个权值。找到这个权值节点,splay到根,把这个节点的后继splay到根的右儿子。

删除这个点。把根设为右儿子。(没有后继,那直接就是左儿子)

(也可以仿照区间删除的方法)

③单点加。同上。

区间操作:

通性:把l-1旋转到根。r+1旋转到根的右儿子。r+1左儿子的子树就是待处理区间。

可以支持懒标记。

懒标记和普通线段树的懒标记一样,作用点直接处理。然后打上标记。

标记必须支持合并、下放。

①区间加:提出区间后,r+1左儿子sum标记

②区间翻转:打翻转标记。同时交换左右儿子。

③区间删除:提出区间,后删除。

④区间插入:不能一个个insert,会被卡成n^2。

x到根,x+1到根右儿子。把要加入的数分治地建成一棵小平衡树。(分治直接保证logn树高)

然后接到x+1的左儿子。

查询操作:

一律先提出区间,然后直接查询根的右儿子的左儿子。

①区间求最大子段和:同线段树。每个节点代表一个区间,维护区间左起最大值,区间右起最大值,区间最大子段和,区间和。

提取完区间,直接查询。

②区间和。

如果出题人丧心病狂,让你维护一个序列,支持以上所有操作怎么办?

以及更多具体操作见:[NOI2005]维护数列——平衡树观止

upda:2018.11.14

Splay还有一个用途:LCT维护实链。

[学习笔记]动态树Link-Cut-Tree

6.数据结构的通性

1.数据结构的题目往往可以O(n^2)暴力写部分分。

考虑我们为什么要用数据结构,什么时候用。

数据结构:二叉堆,左偏树,tire树,栈,队列,哈希,链表,树状数组,并查集,分块,点分治,线段树,动态开点线段树,主席树,二叉查找树,平衡树

①维护正确性。hash主要针对的就是这一点。

②维护复杂度。包括空间和时间复杂度。

空间:主席树,动态开点线段树

时间:剩下的大部分。

还有一些:trie,队列,栈。

数据结构往往都是从维护这两部分的角度出发设计。

2.要分清数据结构和原序列、树本身,否则容易懵。

3.抓住数据结构(尤其平衡树)的形态,就比较容易理解,并且还能推理构造出其他的操作。

[学习笔记]平衡树(Splay)——旋转的灵魂舞蹈家的更多相关文章

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

    坑爹的splay,毁我青春,耗我钱财,颓我精力 是一种用于保存有序集合的简单高效的数据结构.伸展树实质上是一个二叉查找树.允许查找,插入,删除,删除最小,删除最大,分割,合并等许多操作,这些操作的时间 ...

  2. 【学习笔记】splay入门(更新中)

    声明:本博客所有随笔都参照了网络资料或其他博客,仅为博主想加深理解而写,如有疑问欢迎与博主讨论✧。٩(ˊᗜˋ)و✧*。 前言 终于学习了 spaly \(splay\) !听说了很久,因为dalao总 ...

  3. webgl学习笔记三-平移旋转缩放

    写在前面 建议先阅读下前面我的两篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 平移 1.关键点说明 顶点着色器需要加上 uniform vec4 u_Translation ...

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

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

  5. [学习笔记] 平衡树——Treap

    前置技能:平衡树前传:BST 终于学到我们喜闻乐见的平衡树啦! 所以我们这次讲的是平衡树中比较好写的\(Treap\). (以后会写splay的先埋个坑在这) 好了,进入正题. step 1 我们知道 ...

  6. 学习笔记:Splay

    代码适中.非常灵活的平衡树. 需要前置:二叉搜索树. 一些基础的函数: int idx, ch[N][2], cnt[N], sz[N], fa[N]; /* idx 是节点计数, ch[i][0 / ...

  7. 学习笔记 | treap | splay

    目录 前言 treap 它的基本操作 前言 不会数据结构选手深深地感受到了来自treap的恶意QwQ 在听的时候感觉自己听得听懂的??大概只是听懂了它的意思 代码是怎么写都感觉写不好╮(╯﹏╰)╭ 菜 ...

  8. webgl学习笔记五-纹理

    写在前面 建议先阅读下前面我的三篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 webgl学习笔记三-平移旋转缩放 术语 : 纹理 :图像 图形装配区域 :顶点着色器顶点坐标 ...

  9. webgl学习笔记四-动画

    写在前面 建议先阅读下前面我的三篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 webgl学习笔记三-平移旋转缩放   下面我们将讲解下如何让一个正方形动起来~不断擦除和重绘 ...

随机推荐

  1. kubeadm源码修改证书时间 -1.13

    编译后~ 链接:https://pan.baidu.com/s/1ofLX1Sv0ZF2yjkJdqf-6rw 提取码:cnbd 已统一与CA证书都是10年 已测试 适用于k8s 1.10 至 1.1 ...

  2. MySQL基础练习(二)

    第一个例子我们编写一个 SQL 查询,列出所有超过或等于5名学生的课. 先建表 CREATE TABLE courses( student ) NOT NULL, class ) NOT NULL ) ...

  3. cobbler部署以及使用

    常用软件安装及使用目录 资源链接:https://pan.baidu.com/s/1yfVnuSgY5vOTh-B74tpVyw   网盘分享的文件在此 cobbler第一次操作history. ec ...

  4. 初步认识CNN

    1.机器学习 (1)监督学习:有数据和标签 (2)非监督学习:只有数据,没有标签 (3)半监督学习:监督学习+非监督学习 (4)强化学习:从经验中总结提升 (5)遗传算法:适者生存,不适者淘汰 2.神 ...

  5. Daily Scrumming* 2015.11.2(Day 14)

    一.今明两天任务表 Member Today’s Task Tomorrow’s Task 江昊 实现前后端整合 继续实现前后端整合 杨墨犁 修改好首页 开始实现社团页 付帅 测试api 继续测试并完 ...

  6. 20172313『Java程序设计』课程结对编程练习_四则运算第二周阶段总结

    20172313『Java程序设计』课程结对编程练习_四则运算第二周阶段总结 结对伙伴 20172326康皓越 博客地址(http://www.cnblogs.com/326477465-a/p/90 ...

  7. iOS开发学习-类似微信聊天消息中的电话号码点击保存到通讯录中的功能

    类似微信聊天消息中的电话号码点击保存到通讯录中的功能,ABAddress的实现在iOS9中是不能正常使用的,点击完成后,手机会非常的卡,iOS9之后需要使用Contact新提供的方法来实现该功能.快捷 ...

  8. 07_Java基础语法_第7天(练习)_讲义

    今日内容介绍 1.循环练习 2.数组方法练习 01奇数求和练习 * A: 奇数求和练习 * a: 题目分析 * 为了记录累加和的值,我们需要定义一个存储累加和的变量 * 我们要获取到1-100范围内的 ...

  9. 树莓派与Arduino Leonardo使用NRF24L01无线模块通信之基于RF24库 (二) 发送自定义数据

    在我的项目里,树莓派主要作为中心节点,用于接收数据,Arduino作为子节点,用于发送数据,考虑到以后会有很多子节点,但又不至于使得代码过于繁琐,因此所有的传输数据添加一个头部编号用于区分不同节点. ...

  10. boolean类型的按位或||和|的区别

    boolean类型既可以使用&&和||做逻辑运算,也可以使用&和|做逻辑运算,但前者是经过优化的(执行短路运算),后者未优化. 以下代码验证: 逻辑或|| public cla ...