昨晚终于明白了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的双旋的更多相关文章

  1. 浅谈splay(点的操作)

    浅谈splay(点的操作) 一.基本概念 splay本质:二叉查找树 特点:结点x的左子树权值都小于x的权值,右子树权值都大于x的权值 维护信息: 整棵树:root 当前根节点  sz书上所有结点编号 ...

  2. 浅谈splay

    \(BST\) 二叉查找树,首先它是一颗二叉树,其次它里面每个点都满足以该点左儿子为根的子树里结点的值都小于自己的值,以该点右儿子为根的子树里结点的值都大于自己的值.如果不进行修改,每次查询都是\(O ...

  3. 简析平衡树(三)——浅谈Splay

    前言 原本以为\(Treap\)已经很难了,学习了\(Splay\),我才知道,没有最难,只有更难.(强烈建议先去学一学\(Treap\)再来看这篇博客) 简介 \(Splay\)是平衡树中的一种,除 ...

  4. Lct浅谈

    Lct浅谈 1.对lct的认识 ​ 首先要知道$lct$是什么.$lct$的全称为$link-cut-tree$.通过全称可以看出,这个数据结构是维护树上的问题,并且是可以支持连边断边操作.$lct$ ...

  5. 浅谈 Fragment 生命周期

    版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...

  6. 浅谈 LayoutInflater

    浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...

  7. 浅谈Java的throw与throws

    转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...

  8. 浅谈SQL注入风险 - 一个Login拿下Server

    前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...

  9. 浅谈WebService的版本兼容性设计

    在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...

随机推荐

  1. C#编程之神奇程序找数

    C#编程之神奇程序找数 问题1:这个程序要找的是符合什么条件的数? 问题2:这样的数存在么?符合这一条件的最小的数是什么? 问题3:在电脑上运行这一程序,你估计多长时间才能输出第一个结果?时间精确到分 ...

  2. KEIL C51代码优化详细分析

    阅读了<单片机与嵌入式系统应用>2005年第10期杂志<经验交流>栏目的一篇文章<Keil C51对同一端口的连续读取方法>(原文)后,笔者认为该文并未就此问题进行 ...

  3. 四人小组:vip会员管理系统

    需求概述: 针对各类商铺百花齐放的现状,越来越多的商家考虑用各种方式招揽顾客,会员制度一向是吸引回头客的不二法宝.用户持有会员卡能够迅捷的购物,享有普通顾客更多的优惠或回馈.乃至新品推送.积分等一系列 ...

  4. By.cssSelector定位元素一个不足发现

     这个如果用cssSelector定位,代码如下,此时输出的数值是0 System.out.println(driver.findElements(By.cssSelector("div[c ...

  5. PHP中define和defined的区别

    PHP中define和defined的区别 对于初学者会混淆这两个函数 1.define用来定义一个常量,常量也是全局范围的.不用管作用域就可以在脚本的任何地方访问 常量.一个常量一旦被定义,就不能再 ...

  6. [转帖 cnblog 的news ]技术实力超群的Netflix,为何没有CTO

    技术实力超群的Netflix,为何没有CTO https://news.cnblogs.com/n/581824/ 投递人 itwriter 发布于 2017-11-05 16:12 评论(2) 有1 ...

  7. centos6.7 安装JDK

      1.卸载JDK 查看系统是否已安装JDK.一般的linux都默认使用了开源的openJDK.显示JDK版本信息,已经安装JDK,否则没有安装.命令行: [root@localhost ~]# ja ...

  8. cnblog博客CSS定制

    一.页面定制CSS #home { margin: 0 auto; width: 80%;/*原始65*/ min-width: 980px;/*页面顶部的宽度*/ background-color: ...

  9. app流畅度测试--使用SM

    通过测量应用的帧率FPS并不能准确评价App的流畅度,FPS较低并不能代表当前App在UI上界面不流畅,而1s内VSync这个Loop运行了多少次更加能说明当前App的流畅程度. 那么我们可以直接在A ...

  10. rabbitmq 集群安装

    1.安装模式分为三种:单主机模式.普通集群模式.镜像集群模式. 单主机模式:rabbitmq运行在一台主机上,生产环境不建议使用该模式,性能有限.如果该台主机down机,整个服务将不可用. 普通集群模 ...