自底向上伸展树(之字形旋转+一字形旋转)

【0】README

0.1) 本文总结于 数据结构与算法分析,核心剖析路线为原创, 旨在理清 自底向上伸展树(之字形旋转+一字形旋转) 的基本思路;
0.2) 自底向上伸展树 是基于 AVL树,for detailed AVL, please visit http://blog.csdn.net/pacosonswjtu/article/details/50522677 ;
0.2) 对于伸展树的实现而言, 自顶向下伸展树只用到了O(1)的额外空间,且能够保持O(logN)的摊还时间界,通常推荐自顶向下伸展树的应用;for detailed top-down splay tree, please visit http://blog.csdn.net/pacosonswjtu/article/details/50609414 (干货——推荐自顶向下伸展树的应用)


【1】伸展树(之字形旋转+一字形旋转)

1.1)定义:

  • 伸展树保证从空树开始任意连续M次对树的操作最多花费 O(M logN)时间;

1.2)摊还运行时间:

  • 当 M 次操作的序列总的最坏情形运行时间为 O(MF(N))时,我们就说它的摊还运行时间为 O(F(N)), 因此一颗伸展树 每次操作的摊还代价是 O(log N);(摊还 == 分期偿还)

1.3)如果任意特定操作可以有最坏时间界O(N), 而我们仍然要求一个 O(logN)的摊还时间界, 那么很清楚, 只要一个节点被访问, 它就必须被移动。 否则,一旦我们发现一个深层节点,我们就有可能不断对它进行find 操作。 如果这个节点不改变位置, 而每次访问又花费 O(N), 那么M次访问将花费 O(M * N)的时间;
1.4)引入伸展树的原因:

  • 如果任意特定操作可以有最坏时间界O(N), 而我们仍然要求一个 O(logN)的时间复杂度, 显然,为了达到这个目标,只要一个节点被访问了,那么它必须被移动。否则,一旦我们发现一个深层节点,我们就有可能不断对它进行find操作。 如果这个节点不改变位置, 而每次访问又花费了 O(N), 那么M次访问将花费O(MN)的时间; (干货——引入伸展树的原因)

1.5)伸展树的基本想法: (干货——伸展树的基本想法)

  • 1.5.1)当一个节点被访问后, 它就要经过一系列AVL 树的旋转被放到根上。注意, 如果一个节点很深,那么在其路径上就存在许多的节点也相对较深,通过重新构造可以使对所有这些节点的进一步访问所花费的时间变少。
  • 1.5.2)因此,如果节点过深,那么我们还要求重新构造应该具有平衡这棵树(到某种程度)的作用;除了在理论上给出好的时间界外, 这种方法还可能有实际的效用(reasons);
    • r1)因为在许多应用中当一个节点被访问时, 它就很可能不久后再被访问到;
    • r2)另外, 伸展树还不要求保留高度或平衡信息, 因此它在某种程度上节省空间并简化代码;

【2】一个简单的想法(不过行不通)

2.1)执行单旋转:实施上面描述的重新构造的一种方法是执行单旋转,从下到上进行;
2.2)不过这种方法效率不是很高:因为这些旋转的效果是将 k1 一直推向树根,使得对 k1 的进一步访问很容易,不足的是它把另外一个节点 k3 几乎推向和k1以前同样的深度;
2.3)结论(这个想法还不够好):虽然这个策略使得对 k1 的访问花费时间减少,但是它并没有明显的改变访问路径上其他节点的状况;

【3】展开(因为章节2中的方法行不通,所以才有伸展树的展开)

我们仍然是从底部向上沿着访问 路径旋转;
3.1)令X 是在访问路径上的一个节点, 我们将在这个路径上实施旋转操作。

  • 3.1.1)如果X 的父节点是树根, 那么我们只要旋转X 和树根;(这是沿着路径上的最后的旋转)(干货——单旋转定义)
  • 3.1.2)否则, X就有父亲P 和 祖父G, 存在两种情况需要考虑:

    • case1)第一种情况是 之字形:我们就执行一次AVL 那样的双旋转;(访问节点X是P的右儿子, 而父亲P是G的左儿子的形式;或者访问节点X是P的左儿子, 而父亲P是G的右儿子的形式)(干货——之字形旋转情形的定义,即访问节点X 介于父节点P 和 祖父节点G 之间,确切地说是 P≤X≤G)
      这里写图片描述

    • case2)第二种情况是 一字形:我们就把左边的树变成右边的树;(访问节点X 和 父亲P 都分别是父亲P和祖父G的左儿子,或者都是右儿子) (干货——一字形旋转情形的定义 ,即访问节点X 不介于父节点P 和 祖父节点G 之间,确切地说是 X≤P≤G 或 G≤P≤X)
      这里写图片描述

3.2)对展开操作的分析(Analysis)

  • A1)展开操作不仅将访问 的节点移动到根处,而且还有把访问路径上的大部分节点的深度大致减少一半的效果(某些浅的节点最多向下推后两个层次)
  • A2)下图中指出 关键字为1的节点展开的结果 。区别在于:在对关键字1的节点访问(花费N-1个单元的时间)之后,对关键字为2的节点的访问只花费 N/2 个时间单元而不是 N - 2个时间单元;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/331617.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

apache.camel_Apache Camel 3.1 –更多骆驼核心优化(第2部分)

apache.camel我以前曾在博客中介绍我们在下一个Camel 3.1版本(第1部分)中所做的优化 。 今天,我想发布大约4周后的状态更新。 我们集中在三个方面优化骆驼核心: 不必要的对象分配 不必要的方法调用 提高绩效 换句话说&#…

Util包中Arrays

java.util 类 Arrays java.lang.Object -java.util.Arrayspublic class Arrays extends Object此类包含用来操作数组(比如排序和搜索)的各种方法。此类还包含一个允许将数组作为列表来查看的静态工厂。 除非特别注明,否则如果指定数组引用为 …

Android的sqlite使用外部,Android 使用外部已经建立好的sqlite数据库

最近项目需要通过电话号码查询归属地,决定直接在本地sqlite的数据库进行查询,没必要去访问网络(虽然最后还是决定还是将数据库放在服务器上)一 首先先将外部的sqlite数据库放入assets文件夹下面注意:必须是sqlite数据库(XXX.db),如…

java流与文件——操作文件

【0】README 0.1) 本文描述转自 core java volume 2, 旨在理解 java流与文件——操作文件 的相关知识; 0.2) for source code, please visit https://github.com/pacosonTang/core-java-volume/blob/master/coreJavaAdvanced/ch…

阅读副本和Spring Data第2部分:配置基础项目

在上一篇文章中,我们使用相同的数据设置了多个PostgreSQL实例。 下一步将是使用这两个服务器来配置spring项目。 如前所述,由于我们使用完全相同的数据库,因此我们将使用Spring Boot JPA帖子中的一些代码。 这将是我们的gradle构建文件 pl…

java生成UUID通用唯一识别码

一、UUID概述UUID含义是通用唯一识别码 (Universally Unique Identifier),这是一个软件建构的标准,也是被开源软件基金会 (Open Software Foundation, OSF) 的组织在分布式计算环境 (Distributed Computing Environment, DCE) 领域的一部份。 UUID 的目…

android 项目部署,Android发布项目到JCenter

JCenter是什么大家应该都用过各种各样的Github上的第三方开源组件。类似这种效果的compile wang.yuchao.demoforjcenterlibrary:DemoForJCenterLibraryModel:1.2.5我们会比较好奇Android Studio 是从哪里得到这个类库的?Android Studio是从build.gradle里面定义的Ma…

java流与文件——对象流和序列化

【0】README 0.1) 本文描述转自 core java volume 2, 旨在理解 java流与文件——对象流和序列化 的相关知识; 0.2) for source code , please visit https://github.com/pacosonTang/core-java-volume/blob/master/coreJavaAdva…

maven 版本号插件_测试Maven版本插件自动递增版本号

maven 版本号插件抽象 Maven版本插件是一个非常强大的工具,我在很大程度上依赖于它来协调软件版本。 通常,软件发行版本号遵循简单的1.0.0.0-SNAPSHOT格式。 但是最近我需要在版本号中添加一个限定符,例如1.0-beta-SNAPSHOT或1.0.0-fix-bug-d…

java中Date

在类 Date 所有可以接受或返回年、月、日期、小时、分钟和秒值的方法中,将使用下面的表示形式:年份 y 由整数 y - 1900 表示。月份由从 0 至 11 的整数表示;0 是一月、1 是二月等等;因此 11 是十二月。日期(一月中的某…

如何配置android的adb环境变量,如何配置adb环境变量?win7配置adb环境变量的方法...

本文教程小编分享就是win7系统配置adb环境变量的方法, windows7系统 电脑安装adb工具时,提示“adb不是内部或外部命令”这时候我们需要重新配置adb环境变量,那么win7系统怎么配置adb环境变量?网上介绍配置adb环境变量的方法比较少…

jep290涉及jdk版本_JDK 14 / JEP 305模式匹配“ Smart Casts”实例

jep290涉及jdk版本我通常将Java代码中instanceof运算符的存在视为“ 红色标志 ”,这意味着在某些情况下使用instanceof不一定是错误的,但是使用它有时表示可以通过更干净的方式解决设计问题,如所述本文结尾处引用的一些资源中的内容&#xff…

java中Date与DateFormat的格式输出

一、DateFormat java.text.DateFormat 使用 getDateInstance 来获取该国家/地区的标准日期格式。另外还提供了一些其他静态工厂方法。使用 getTimeInstance 可获取该国家/地区的时间格式。使用 getDateTimeInstance 可获取日期和时间格式。可以将不同选项传入这些工厂方法&…

二叉堆的操作总结(insert+deleteMin+increaseKey+decreaseKey+percolateDown+percolateUp)

【0】README 本文idea 均为原创, for source code, please visit https://github.com/pacosonTang/dataStructure-algorithmAnalysis/tree/master/chapter6/p140_binaryheap_conclusion 【1】insert操作 // Attention, the index of the heap starts from 1 void …

aws生态系统集成商_通过通用数据访问扩展AWS生态系统

aws生态系统集成商Amazon Web Services(AWS)可帮助组织托管和管理其数据流程,例如构建数据可视化和执行ETL任务。 在CData,我们可以轻松地将AWS Services与异构业务应用程序和分布式数据存储连接起来,以最终帮助企业对…

HTML.parser和正则解析,正则表达式+HTMLParser使用详.ppt

getText:/body getText: getText:/htmlgetText:除了前面3.2中输出的几个Tag,其余的Tag都在这里了。 3.4 XorFilter 把前面的AndFilter换成NotFilter测试代码: NodeFilter filterID new HasAttributeFilter( "id" );NodeFilter filterChild n…

FileDescriptor的作用

一、FileDescriptor 文件描述符类的实例用作与基础机器有关的某种结构的不透明句柄,该结构表示开放文件、开放套接字或者字节的另一个源或接收者。文件描述符的主要实际用途是创建一个包含该结构的 FileInputStream 或 FileOutputStream。 二、静态标准文件描述…

java流与文件——内存映射文件

【0】README 0.1) 本文描述转自 core java volume 2, 旨在理解 java流与文件——内存映射文件 的相关知识; 0.2)内存映射文件的目的是: 提高访问速度, 缓冲区Buffer; 0.3) 本文干…

java 函数式编程 示例_功能Java示例 第8部分–更多纯函数

java 函数式编程 示例这是第8部分,该系列的最后一部分称为“示例功能Java”。 我在本系列的每个部分中开发的示例是某种“提要处理程序”,用于处理文档。 在上一期文章中,我们已经使用Vavr库看到了一些模式匹配,并且还将故障也视…

html加css作品,我的影视作品,如何在博客园发布带有CSS样式的HTML

总结一下,我做过的视频:(顺便试试在博客园如何发HTML网页)发布网页总结:HTML可以正常发送,但最好将你要发布的html文件放在一个带有ID的div中,这样方便后期添加样式时通过ID添加,不会影响到网页中的其他布局…