浅谈splay的双旋
昨晚终于明白了splay双旋中的一些细节,今日整理如下
注:题目用的2002HNOI营业额统计,测试结果均来及codevs 网站的评测结果 http://codevs.cn/problem/1296/
本题完整代码请见http://www.cnblogs.com/TheRoadToTheGold/p/6372009.html
1、这是旋转部分的代码
inline void splay(int x,int goal)
{
while(pre[x]!=goal)
{
int y=pre[x];
int kind=ch[y][]==x;
if(pre[y]==goal) rot(x,kind);//父节点是目标节点,单旋
else
{
kind=ch[pre[y]][]==y;
if(ch[y][!kind]==x)//一字型
{
rot(y,kind);
rot(x,kind);
}
else//之字型
{
rot(x,!kind);
rot(x,kind);
}
}
}
root=x;
}
理解较浅,目前认为之字形旋转的本质就是单旋,一字型才算双旋
2、双旋与单旋的区别
先看看运行结果
左边是单旋,右边是双旋,空间几乎一样,时间差距很大
why?
图1:
图2的单旋结果
图2:
双旋结果
可以发现,双旋之后的层数要比单旋之后的层数少1
这只是5层(本图中第6层对5不干扰),如果层数更多呢
所以,双旋层数比单旋要更少
手推一下,上图中第1次旋转结果的树的形态与单旋结果的树的形态是一样的,只是4和3换了个位
所以双旋的优越性在一字型层数>4时才会体现
为什么双旋层数要少?
继续观察图2的第2个和第3个,发现少的那一层是因为4和1处在了同一层
即双旋 使 待旋转点的旋转方向的孩子 与待旋转点的爷爷节点 处在同一层
换用字母表示:
设a的旋转方向的孩子是b,a的父节点是c,c的父节点是d
那么双旋使b、d处在同一层,因为b、d都成为了c的孩子
为什么?分析双旋的两次旋转
先旋转父节点,使爷爷节点和自己都成为父节点的孩子,此时父节点和自己处在同一层,原来的爷爷节点成为自己的父节点
然后旋转自己,自己旋转方向的孩子节点成为自己现在父节点(原先爷爷节点)的孩子,也就是和自己原先父节点处在了同一层
这也是我认为之字型旋转也是单旋的原因,因为之字型旋转是让自己旋转2次,与单旋并无不同
3、旋转顺序
A、代码中一字型旋转顺序是先转父节点,再转自己
①不能改成先转自己,再转父节点
先转自己让自己到父节点的位置,父节点到自己的孩子位置,再转父节点,又转回去了,跟没转一个样
②可以改成旋转自己两次,但那样就相当于单旋
B、之字型旋转的旋转顺序是连续转自己2次
看图,
可以发现连续转自己两次,每次使自己上移一层
而如果先转父节点,可以发现自己原来在哪儿还在那儿,只是父节点和爷爷节点换了而已,相当于这一次白转了
当然你也可以先转父节点,再转自己(两次旋转方向相同),因为的正确性是有保证的
对比一下,上边是先转父节点,再转自己,下边是连续转自己两次(一字型旋转均是先转父节点,再转自己)
上边空间明显大,时间也多点儿
浅谈splay的双旋的更多相关文章
- 浅谈splay(点的操作)
浅谈splay(点的操作) 一.基本概念 splay本质:二叉查找树 特点:结点x的左子树权值都小于x的权值,右子树权值都大于x的权值 维护信息: 整棵树:root 当前根节点 sz书上所有结点编号 ...
- 浅谈splay
\(BST\) 二叉查找树,首先它是一颗二叉树,其次它里面每个点都满足以该点左儿子为根的子树里结点的值都小于自己的值,以该点右儿子为根的子树里结点的值都大于自己的值.如果不进行修改,每次查询都是\(O ...
- 简析平衡树(三)——浅谈Splay
前言 原本以为\(Treap\)已经很难了,学习了\(Splay\),我才知道,没有最难,只有更难.(强烈建议先去学一学\(Treap\)再来看这篇博客) 简介 \(Splay\)是平衡树中的一种,除 ...
- Lct浅谈
Lct浅谈 1.对lct的认识 首先要知道$lct$是什么.$lct$的全称为$link-cut-tree$.通过全称可以看出,这个数据结构是维护树上的问题,并且是可以支持连边断边操作.$lct$ ...
- 浅谈 Fragment 生命周期
版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...
- 浅谈 LayoutInflater
浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...
- 浅谈Java的throw与throws
转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...
- 浅谈SQL注入风险 - 一个Login拿下Server
前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...
- 浅谈WebService的版本兼容性设计
在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...
随机推荐
- Hadoop初探
本文转自:https://blog.csdn.net/column/details/14334.html 前言 Hadoop是什么? 用百科上的话说:“Hadoop是一个由Apache基金会所开发的分 ...
- selenium 关键字驱动部分设计思路
1 说明: 1.以下的代码亲测直接可用, 2.设计思路来自博客园的 张飞_ :http://www.cnblogs.com/zhangfei/p/5330994.html / http://w ...
- springmvc上传文件报错org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.web.multipart.MultipartFile]
在用springmvc+mybatis进行项目开发时,上传文件抛异常... org.springframework.beans.BeanInstantiationException: Could no ...
- linux ls文件颜色和底色设置
转帖 :linux ls文件颜色和底色设置 白色:表示普通文件蓝色:表示目录绿色:表示可执行文件红色:表示压缩文件浅蓝色:链接文件红色闪烁:表示链接的文件有问题黄色:表示设备文件灰色:表示其他文件 这 ...
- Java开发中的23种设计模式详解(转载)
前学习过一段时间的设计模式,总是感觉学习的不够清楚.现在再重新复习一下,原文地址:https://blog.csdn.net/doymm2008/article/details/13288067 一. ...
- 深入理解JAVA虚拟机阅读笔记5——Java内存模型与线程
Java内存模型是定义线程共享的变量的访问规则(实例字段.静态字段和构成数组对象的元素),但不包括线程私有的局部变量和方法参数. 1.主内存与工作内存 Java内存模型规定,所有的变量都必须存储在主内 ...
- DAY6-Flask项目
1.ViewModel:处理原始数据:裁剪修饰合并 2.访问静态资源 默认情况下,访问的路径为app根目录的下的static文件,为什么说app是根目录而不是fisher.py下,因为在实例化对象的时 ...
- BZOJ3481 DZY Loves Math III(数论+Pollard_Rho)
考虑对于每一个x有多少个合法解.得到ax+by=c形式的方程.如果gcd(x,y)|c,则a在0~y-1范围内的解的个数为gcd(x,y).也就是说现在所要求的是Σ[gcd(x,P)|Q]*gcd(x ...
- 十三个有彩蛋的Linux命令
原文链接: https://my.oschina.net/u/4045573/blog/2986313 一键下载安装配置文本全部命令所需环境 sudo apt-get updategit clon ...
- Common Substrings POJ - 3415(长度不小于k的公共子串的个数)
题意: 给定两个字符串A 和 B, 求长度不小于 k 的公共子串的个数(可以相同) 分两部分求和sa[i-1] > len1 sa[i] < len1 和 sa[i-1] < ...