伸展树(Splay)

Splay 是一种二叉查找树,它通过不断将某个节点旋转到根节点,使得整棵树仍然满足二叉查找树的性质,并且保持平衡而不至于退化为链。它由 Daniel Sleator 和 Robert Tarjan 发明。

旋转

旋转(Rotate)的最终目的是将该节点的深度 − 1 -1 −1并且保证二叉搜索树的结构不改变。

根据节点 x x x是父节点的左子节点或者是右子节点分为右旋和左旋转。

我们以右旋为例,我们发现,如果我们想让节点 X X X的深度 − 1 -1 −1,我们必须让 X X X做 Z Z Z的子节点,至于是左右子节点,取决于 Y Y Y的位置,因为 X X X是代替 Y Y Y的位置。那么 b b b就可以做 Y Y Y的左节点,进而 Y Y Y做 X X X的右节点。

上述过程就是节点右旋的过程,我们将 X X X的深度 − 1 -1 −1而不改变二叉搜索树的性质。

而左旋正好和右旋对称,读者可以自己尝试推导一下。

这两种情况对应的选择操作也叫做Zig。

我们可以将这两个操作结合成一个函数,让这个函数自己判断是左旋还是右旋。


void rotate(int x)
{// 获取父节点和祖父节点int y = tree[x].fa;int z = tree[y].fa;// 连接祖父节点和Xif (tree[z].l == y)tree[z].l = x;elsetree[z].r = x;tree[x].fa = z;// 连接父节点和X的子节点,连接父节点和Xif (tree[y].l == x){tree[y].l = tree[x].r;tree[tree[x].r].fa = y;tree[x].r = y;tree[y].fa = x;}else{tree[y].r = tree[x].l;tree[tree[x].l].fa = y;tree[x].l = y;tree[y].fa = x;}
}

伸展

伸展(Splay)是伸展树的核心操作,其最终目的是将节点 X X X一直向上选择直到作为节点 R R R的子节点为止或者将 X X X一直旋转到树的根节点为止。

除了完成最终目的,我们还要尽可能的降低BST的深度。

伸展分为三种操作,Zig,Zig-Zig和Zig-Zag。

  • 如果 R R R就是 X X X的祖父节点,那么我们直接一次旋转 X X X即可达成目的,这种情况叫做Zig。
  • 如果 X Y Z XYZ XYZ三者共线,那么我们先旋转 Y Y Y,再旋转 X X X。这种情况叫做ZIg-Zag。是双旋操作。
  • 如果 X Y Z XYZ XYZ三者不共线,那么我们先旋转 X X X,再旋转 X X X。这种情况叫做ZIg-Zig。也是是双旋操作。

为什么要三者共线的时候要先旋转 Y Y Y再旋转 X X X,这种双旋转结构可以降低树的层数。在 H > 4 H>4 H>4的时候才能看出来效果。具体参考:

Splay的效率讨论

那我们就可以写出代码。

void splay(int x, int r)
{int y;while ((y = tree[x].fa) != r) // 如果y不是目标节点{int z = tree[y].fa; // 获取祖父节点if (z != r) // 如果z是不是目标节点{// 执行双旋转if (tree[z].l == y && tree[y].l == x || tree[z].r == y && tree[y].r == x)rotate(y);elserotate(x);rotate(x);}elserotate(x); // 直接单旋即可}if (r == 0)root = x;
}

其他操作

其他查询、插入、删除等操作和二叉搜索树完全一直,只不过在找到目标节点之后,要将该节点Splay一下。

Splay与其他二叉搜索树不同的是Splay操作,可以把任意一个节点接到其子节点上,通常用两边夹的方法筛选节点。

P3391 文艺平衡树

伸展树(Splay)相关推荐

  1. 伸展树(Splay tree)图解与实现

    伸展树(Splay tree)图解与实现 伸展树(Splay tree)图解与实现_小张的专栏-CSDN博客_splay树 Splay树详解 Splay树详解 - 秦淮岸灯火阑珊 - 博客园 平衡树 ...

  2. splay tree java_伸展树(splay tree)自顶向下的算法

    伸展树(splay tree)是一种能自我调整的二叉搜索树(BST).虽然某一次的访问操作所花费的时间比较长,但是平摊(amortized) 之后的访问操作(例如旋转)时间能达到O(logn)的复杂度 ...

  3. 伸展树(Splay tree)浅谈

    树看的越来越多,越来越神奇. 看伸展树这种神级数据结构之前,建议大家首先彻底明白二叉搜索树,这是万树的基础. 然后可以去看下treap,最好再去看下红黑树.如果有线段树的基础那更好了,我们会发现线段树 ...

  4. [学习笔记] 伸展树splay详解+全套模板+例题[Luogu P3369 【模板】普通平衡树]

    文章目录 引入概念 全套模板 变量声明 update ==rotate旋转== splay操作 insert插入 delete删除 查找x的位置 查找第k大 前驱/后继 极小值-inf和极大值inf的 ...

  5. [Splay伸展树]splay树入门级教程

    首先声明,本教程的对象是完全没有接触过splay的OIer,大牛请右上角.. 首先引入一下splay的概念,他的中文名是伸展树,意思差不多就是可以随意翻转的二叉树 PS:百度百科中伸展树读作:BoGa ...

  6. 伸展树 Splay 模板

    学习Splay的时候参考了很多不同的资料,然而参考资料太杂的后果就是模板调出来一直都有问题,尤其是最后发现网上找的各种资料均有不同程度的错误. 好在啃了几天之后终于算是啃下来了. Splay也算是平衡 ...

  7. sgu 187 Twist and whirl - want to cheat 伸展树(splay)

    裸的区间翻转..直接写个splay就行... #include <iostream> #include <cstdio> #include <algorithm> ...

  8. AVL树、splay树(伸展树)和红黑树比较

    AVL树.splay树(伸展树)和红黑树比较 一.AVL树: 优点:查找.插入和删除,最坏复杂度均为O(logN).实现操作简单 如过是随机插入或者删除,其理论上可以得到O(logN)的复杂度,但是实 ...

  9. PHP算法 《树形结构》 之 伸展树(1) - 基本概念

    伸展树的介绍 1.出处:http://dongxicheng.org/structure/splay-tree/ A. 概述 二叉查找树(Binary Search Tree,也叫二叉排序树,即Bin ...

  10. 【题集】AVL树、伸展树、红黑树、二叉查找树、替罪羊树的时间复杂度

    目录 1. AVL树 2.伸展树 3.红黑树 4.二叉查找树 5.替罪羊树 1. AVL树 AVL树是最先发明的自平衡二叉查找树.在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平 ...

最新文章

  1. Swift 值类型和引用类型的内存管理
  2. Oracle 免费的数据库--Database 快捷版 11g 安装使用与SOD框架对Oracle的CodeFirst支持...
  3. java 算法--洗牌算法
  4. mysql 表名和和数据库函数名称冲突的解决方法
  5. c字符串分割成数组_leetcode第31双周赛第三题leetcode1525. 字符串的好分割数目
  6. 团队作业8——第二次项目冲刺(Beta阶段)博客汇总
  7. 这些分布式事务的解决方案,你都知道吗
  8. React开发(189):ant design textarea允许清除allowClear
  9. 【版本发布】Jeecg-P3 1.0 发布,J2EE微服务框架(插件开发)
  10. 加拿大上市矿企Bitfarms完成第二笔1500万美元普通股私人认购
  11. java矩形碰撞检测_MonoGame中碰撞检测矩形的起源
  12. matlab 韦布尔拟合,MATLAB数据拟合工具在数学建模中的简单应用
  13. 高标清上下变换器的测试评估及应用研究
  14. 数据库实体、关系(一对一实现方式、一对多实现方式、多对多实现方式)
  15. 操作系统介绍,为什么使用虚拟机,虚拟机使用原理透彻解释
  16. 获取B站某用户更多的关注数和粉丝数
  17. Java实现阿里云域名动态解析,DDNS功能
  18. 把两个数和告诉A,积告诉B,A说不知道是多少, B也说不知道,这时A说我知道了, B接着说我也知道了,求这两个数是什么
  19. 使用Vue前端框架实现知乎日报app
  20. Linux 驱动开发 五:Linux LED驱动开发

热门文章

  1. kprobe 的 3 种使用
  2. 领英如何发布动态与查看自己一共发了多少条动态
  3. 咏南中间件跨平台解决方案
  4. Matlab自带的分类学习工具箱(SVM、决策树、Knn等分类器)
  5. 信用评分模型中的滚动率分析
  6. 胃与十二指肠溃疡的食疗方
  7. 主流智能手机屏幕材质介绍
  8. vm虚拟机安装lede旁路由_利用VMM虚拟机 安装LEDE旁路由 实现软路由超强功能
  9. 夜晚怎么能不吃宵夜呢
  10. 【Python】杂记