浅谈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等,我们要满足以上所 ...
随机推荐
- BETA5/7
前言 我们居然又冲刺了·五 团队代码管理github 站立会议 队名:PMS 530雨勤(组长) 过去两天完成了哪些任务 前一份代码方案全部垮掉,我,重构啦 接下来的计划 加速加速,一定要完成速度模块 ...
- HDU 3092 Least common multiple 01背包
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3092 Least common multiple Time Limit: 2000/1000 MS ...
- Gradle入门(4):依赖管理
在现实生活中,要创造一个没有任何外部依赖的应用程序并非不可能,但也是极具挑战的.这也是为什么依赖管理对于每个软件项目都是至关重要的一部分. 这篇教程主要讲述如何使用Gradle管理我们项目的依赖,我们 ...
- Scrum Meeting Beta - 5
Scrum Meeting Beta - 5 NewTeam 2017/12/4 地点:主楼2楼走廊 任务反馈 团队成员 完成任务 计划任务 安万贺 完成了离线状态进入app的功能 实现离线状态读取本 ...
- python response.text和response.content的区别
1.重点理解 response.text返回的类型是str response.content返回的类型是bytes,可以通过decode()方法将bytes类型转为str类型 推荐使用:respo ...
- Java中线程安全的集合
如果多线程并发的访问与一个数据结构,那么很容易破坏一个数据结构. 例如,一个线程可能要向一个散列表中插入一条数据的过程中,被剥夺了控制权.如果另外一个线程也开始遍历同一个链表,很可能造成混乱,抛出异常 ...
- 【CF995F】Cowmpany Cowmpensation(动态规划,拉格朗日插值)
[CF995F]Cowmpany Cowmpensation(多项式插值) 题面 洛谷 CF 题解 我们假装结果是一个关于\(D\)的\(n\)次多项式, 那么,先\(dp\)暴力求解颜色数为\(0. ...
- BZOJ 1499 [NOI2005] 瑰丽华尔兹 | 单调队列优化DP
BZOJ 1499 瑰丽华尔兹 | 单调队列优化DP 题意 有一块\(n \times m\)的矩形地面,上面有一些障碍(用'#'表示),其余的是空地(用'.'表示).每时每刻,地面都会向某个方向倾斜 ...
- Jump Game - LeetCode
目录 题目链接 注意点 解法 小结 题目链接 Jump Game - LeetCode 注意点 解法 解法一:贪心算法,只关注能到达最远距离,如果能到达的最远距离大于结尾说明能到达,否则不能.并且如果 ...
- 洛谷 P1878 舞蹈课 解题报告
P1878 舞蹈课 题目描述 有\(n\)个人参加一个舞蹈课.每个人的舞蹈技术由整数来决定.在舞蹈课的开始,他们从左到右站成一排.当这一排中至少有一对相邻的异性时,舞蹈技术相差最小的那一对会出列并开始 ...