优先队列——斐波那契堆(without source code)

【0】README

0.1) 本文部分内容转自 数据结构与算法分析,旨在理解 斐波那契堆 的基础知识;
0.2) 文本旨在理清 斐波那契堆的 核心idea,还没有写出源代码实现,表遗憾;
0.3)从实际角度看: 除了某些需要管理大量数据的应用外,对于大多数应用,斐波那契堆的常数因子和编程复杂性使得它比起普通二项堆(二项队列)并不是那样适用;
0.4)斐波那契堆(Fibonacci heap)通过添加两个新的观念推广了二项队列(Notions): (干货——斐波那契堆通过添加两个新的观念推广了二项队列(Notions))

  • N1)DecreaseKey 的一种不同的实现方法:以前的方法是把元素朝向根节点上滤。对于这种方法似乎没有理由期望O(1)的摊还时间界,故需要新的方法;
  • N2)懒惰合并(lazy merging): 只有当两个堆需要合并的时候才 合并。 对于懒惰合并,merge是低廉的, 但是因为懒惰合并并不实际把树结合到一起,所以deleteMin 操作可能会遇到许多的树, 从而使这种操作的代码高昂; 任何一次 deleteMin 都可能花费线性时间, 但是总能够把时间归咎到前面的一些 merge操作中去。特别地, 一次昂贵的deleteMin 必须在其前面要有大量的非常低廉的 merge操作, 它们能够存储额外的位势;(干货——懒惰合并定义)

【1】切除左式堆中的节点

1.1)problem+solution:

  • 1.1.1)problem:如果代表优先队列的树不具有 O(logN)的深度,那么这种方法不适用。例如,若将这种方法用于左式堆,则 decreaseKey 操作可能花费 Θ(N)时间, 如下图所示:
    这里写图片描述
  • 1.1.2)solution: 我们不想把0 上滤到根,因为正如我们看到的那样,存在一些情况使得这样做代价太大。解决方法是把堆沿虚线 切开,如此得到两棵树,然后再把这两棵树合并为一颗树。

1.2)具体操作

  • 1.2.1)令 X 为 要执行decreaseKey 操作的节点, 令 P 为它的父节点;在切断以后,我们得到两棵树,即根为X的 H1 和 T2, T2 是原来的树除去 H1 后 得到的树;

1.3)problem+solution:

  • 1.3.1)problem:如果这两棵树都是左式堆,那么它们可以以时间O(logN)合并完成了。但问题是, T2 未必是左式堆;
  • 1.3.2)solution: 容易恢复左式堆的性质,这要用到下列两个观察到的结论(Conclusions):

    • C1)只有从P 到 T2 的根的路径上的节点可能破坏左式堆的性质, 它们可以通过变换子节点来调整;
    • C2)由于最大右路径最多有 」log(N)+1」个节点,因此我们只需要检查从P 到 T2 的根的路径上的 前 」log(N)+1」 个节点; 将T2 转换为 左式堆H2 后的结构如图11-13所示:

1.4)因为 我们能够以 O(logN) 步将T2 转变成左式堆H2, 然后合并H1 和 H2, 所以得到一个在左式堆中执行 decreaseKey 的O(logN) 算法;合并后的最后结果如图11-14所示:

这里写图片描述


【2】二项队列的懒惰合并

2.1)由斐波那契堆所使用的第二个想法是懒惰合并: 我们将把这个想法用于二项队列并证明执行一次merge操作(还有插入操作,它是一种特殊操作)的摊还时间为 O(1)。对于 deleteMin操作,其摊还时间仍然是 O(logN); (干货——由斐波那契堆所使用的第二个想法是懒惰合并)
2.2)懒惰合并定义: 为了合并两个二项队列, 只要把两个二项树的表连在一起,结果得到一个新的二项队列。这个新的二项队列可能含有相同大小的多棵树,因此破坏二项队列的性质。为了保持一致性,我们将把它叫做 懒惰二项队列(lazy nominal queue)。这是一种快速操作, 该操作总是花费常数时间。和前面一样, 一次插入通过创建一个单节点二项队列并将其合并而完成。 区别在于合并是懒惰的 。 (干货——懒惰合并定义 + 懒惰二项队列定义)
Attention)懒惰二项队列和标准二项队列的区别(Differentiation):

  • D1)懒惰二项队列: 允许有高度相同的二项树存在该队列中;
  • D2)标准二项队列: 不允许有高度相同的二项树存在该队列中;

2.3)deleteMin 操作要麻烦得多, 因为此处需要我们最终把懒惰二项队列转换为 标准的二项队列, 不过,它仍然花费O(logN)的摊还时间——而不像以前是O(logN)最坏情形时间。为了执行 deleteMin , 我们找出(并最终返回)最小元素。如前所述,我们将它从队列中删除, 使得它的每一个子节点都成为一颗新的 树。此时我们通过合并两颗相等大小的树直至不再可能合并为止而把所有的树合并成一个二项队列;

  • Attention)什么时候需要将懒惰二项队列进行合并? (干货——什么时候需要将懒惰二项队列进行合并?)
    • A1)懒惰二项队列的定义: 是在需要的时候才进行合并;不需要的时候不进行合并,即只是将二项树的表(根)连在一起而已;
    • A2)懒惰二项队列需要合并的时候是: 当在执行 deleteMin 操作之后 ,需要将 懒惰二项队列进行真正的合并;(after deleteMin operation)

2.4)看个荔枝:

  • 2.4.1)懒惰二项队列如图11-15 所示:
    这里写图片描述

  • 2.4.2)为了执行deleteMin, 我们删除最小元素,得到的懒惰二项队列如图11-16所示:
    这里写图片描述

  • 2.4.3)现在我们必须将所有的树合并而得到一个标准的二项队列:使用的算法伪代码如下:
    这里写图片描述

  • 对上述算法的分析(Analysis): 上述的 for 循环计数 和 while 循环末尾的检测花费 O(logN) 时间, 这使得运行时间成为所要要求的 O(T+logN)。

  • 2.4.4)图11-18 显示该算法对前面二项树的集合的执行情况:
    这里写图片描述

2.5)懒惰二项队列的摊还分析

  • 定理11.3: merge 和 insert 的摊还运行时间对于懒惰二项队列均为 O(1), 而deleteMin的摊还运行时间为 O(logN);

【3】斐波那契堆操作(注意区分deleteMin 和 decreaseKey 操作)

3.1)正如我们前面提到的那样: 斐波那契堆将左式堆 decreaseKey 操作与懒惰二项队列merge操作结合起来。不过,我们不能一点都不修改。 (干货——斐波那契堆的核心思想)

  • 3.1.1)问题在于: 如果在这些二项树中进行任意切割,那么结果得到的森林将不再是二项树的集合了。因此,每一颗树的秩最多为 」logN」 将不再成立;
  • 3.1.2)由于 在懒惰二项队列中 deleteMin 的摊还时间已被证明是 2logN + R,因此,对于deleteMin 的界,我们需要 R = O(logN)成立;

3.2) 为了保证R=O(logN), 我们对所有的非根节点应用下述法则(rules):

  • r1)将第一次(因为切除而)失去一个子节点的(非根)节点做上标记;
  • r2)如果被标记的节点又失去另外一个儿子节点, 那么将其从它的父节点切除。这个节点现在变成了一颗分离的树的根并且不再被标记。这叫做一次 级联切除,因为在一次 decreaseKey 操作中可能出现多次这种切除; (干货——级联切除定义)

3.2)看个荔枝(注意和上述变换法则相结合):

  • 3.2.1)图11-19 显示了在 decreaseKey 之前斐波那契堆中的一颗树(被标记的节点有: 8,11, 10, 17, 33)。 (干货——现在讲的操作是 decreaseKey)
    这里写图片描述

    • step1)当关键字为 39 的节点变为12的 时候,堆序被破坏;
    • step2)由于包含33的节点已经被标记了(在对39进行decrease之前),那么这是它的第二个失去的子节点,从而它也被从它的父节点(10)中切除;(2nd rule applied)
    • step3) 10也失去了它的第二个儿子, 于是10 从 根为5的树中被切除;(2nd rule applied)
    • step4)切除过程结束,因为 5 是 未做标记的。现在把 节点5 做上标记, 如图11-20所示:(1st rule applied)

Attention)过去被做过标记的节点10 和33 不再被标记, 因为现在他们都是根节点, 这在时间界的证明中是极其重要的;(Attention——过去被做过标记的节点10 和33 不再被标记, 因为现在他们都是根节点。)
这里写图片描述

补充:intro to 斐波那契堆(转自http://dsqiu.iteye.com/blog/1714961)

  • 斐波那契堆(Fibonacci Heap):斐波那契堆是一种松散的二项堆,与二项堆的主要区别在于构成斐波那契堆得树可以不是二项树,并且这些树的根排列是无须的(二项堆的根结点排序是按照结点个数排序的,不是按照根结点的大小)。斐波那契堆得优势在于它对建堆、插入、抽取最小关键字、联合等操作能在O(1)的时间内完成(不涉及删除元素的操作仅需要O(1))。这是对二项堆效率的巨大改善。但由于斐波那契堆得常数因子以及程序设计上的复杂度,使它不如通常的二叉堆合适。因此,它的价值仅存在于理论意义上。
  • 斐波那契堆的另一个特点就是: 合并操作只发生在抽取一个结点之后,也就是说斐波那契堆的维护总是会延后的(个人根据代码理解的)。 (干货——斐波那契堆与二项堆(二项队列)的区别)

【4】时间界的证明

  • 定理11.4:斐波那契堆对于 insert,merge 和 decreaseKey 的摊还时间界均为 O(1), 而对于deleteMin 则是 O(logN);

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

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

相关文章

计算机专业考研可关注哪些公众号,考研应关注哪些公众号?

考研应关注哪些公众号?2018-11-30深夜睡不着,看到了这个问题,觉得我能帮上忙,就坐起来写了一份回答(^_^)微信公众号有:考研狗之家(特别推荐,各种资源)考研军火库(特别推荐,各种技巧)考研圈考研资…

cassandra 备份_使用sstableloader恢复Cassandra Priam备份

cassandra 备份我之前曾写过关于设置Cassandra和Priam进行备份和集群管理的文章。 但是,我在此处提供的用于备份还原的示例并不适用于所有情况,例如,它可能不适用于完全独立的群集。 或者在部分还原到一个表而不是整个数据库的情况下。 在这…

XML——XML概述

【0】README 0.1)本文描述 转自 core java volume 2, 旨在理解 XML——XML概述 的基础知识; 【1】XML概述相关 1)problemsolution (干货——引入XML的原因) 1.1)problem:1.1.1&am…

java入门配置

一、下载安装JDK JDK下载路径:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 点击 Accept License Agreement ,选择自己的系统类型JDK下载,然后安装JDK。 二、安装JDK 双击JDK运行,选择…

华中科技大学计算机学院发表论文规定,华中科技大学等7所大学取消“研究生毕业必须发表论文”要求...

华中科技大学等7所大学取消“研究生毕业必须发表论文”要求北京晨报发表于 2006/07/17 10:51中国7所大学取消“研究生毕业必须发表论文”要求中新网7月16日电据《北京晨报》报道,昨天,记者从大学校长论坛了解到,中国人民大学、北京师范大学、…

计算机网络中的广播啥意思,开启无线广播啥意思

大家好,我是时间财富网智能客服时间君,上述问题将由我为大家进行解答。以路由器为例,开启无线广播是指开启无线路由器功能。路由器(Router,又称路径器)是一种计算机网络设备,它能将数据包通过一个个网络传送至目的地(选…

jep290涉及jdk版本_JDK 14 – JEP 361从预览中切换表达式

jep290涉及jdk版本在我的前一篇文章中 ,我写了有关作为JDK 12的预览功能发布的开关表达式和相关增强功能的信息。随后,在JDK 13中提出了一些更改,例如使用yield关键字从switch块返回值并在预览中发布。 在即将于明年3月在GA上市的即将发布的…

java变量作用域Scope

一、变量Scope 作用域同时决定了它的“可见性”以及“存在时间”。在C,C和Java里,作用域是由花括号的位置决定的。变量的作用域分为四个级别:类级、对象实例级、方法级、块级。 二、类级Scope 类级变量又称全局级变量或静态变量&#xff0c…

XML——解析XML文档

【0】README 0.1)本文描述 转自 core java volume 2, 旨在理解 XML——解析XML文档 的基础知识; 0.2) for source code, please visit https://github.com/pacosonTang/core-java-volume/blob/master/coreJavaAdvanced/chapter2…

计算机维修与维护入门,计算机组装与维护基础知识

《计算机组装与维护基础知识》由会员分享,可在线阅读,更多相关《计算机组装与维护基础知识(5页珍藏版)》请在人人文库网上搜索。1、计算机组装与维护基础知识关键考点:CPU主板内存硬盘显卡CMOS硬件组装操作系统学生姓名:总分&…

java oauth2.0_OAuth 2.0 Java指南:5分钟保护您的应用程序安全

java oauth2.0使用Okta的身份管理平台轻松部署您的应用程序 使用Okta的API在几分钟之内即可对任何应用程序中的用户进行身份验证,管理和保护。 今天尝试Okta。 现代应用程序依赖于用户身份验证,但是它可能给Java开发人员带来困难的挑战,以及…

Java编程规范

一、常见命名规则 (1)匈牙利命名法 比 较著名的命名规则是匈牙利命名法,但这种命名法对于跨平台移植简直是灾难。这种命名方法是由Microsoft程序员查尔斯西蒙尼(Charles Simonyi) 提出的。其主要思想是“在变量和函数名中加入前缀以增进人们对程序的理解”。匈牙利…

XML—— 验证XML文档

【0】README 0.0)本文文字描述转自 core java volume 2 , 旨在理解 XML—— 验证XML文档 的基础知识 0.1)problemsolution (干货——不推荐使用DOM 技术解析XML) 0.1.1)problem:如果仅仅按照…

计算机数据链路层教案,第三章 数据链路层(2) 新.ppt

文档介绍:计算机通信网20112011年教案年教案作者:段景山作者:段景山杨宁杨宁毛玉明毛玉明2第三章数据链路层??链路层功能链路层功能??成帧成帧??差错检测和纠正差错检测和纠正??差控与流控协议差控与流控协议??协议描述与验证协议描述与验证??示例示例?…

java导出javadoc文档

一、注释 (1)文档注释的格式化 生成的文档是 HTML 格式,而这些 HTML 格式的标识符并不是 javadoc 加的,而是我们在写注释的时候写上去的。比如,需要换行时,不是敲入一个回车符,而是写入 <br>&a…

java内核_测量时间:从Java到内核再到

java内核问题陈述 当您深入研究时,即使是最基本的问题也会变得很有趣。 今天,我想深入研究一下Java时间。 我们将从Java API的最基础知识开始,然后逐步降低堆栈:通过OpenJDK源代码glibc一直到Linux内核。 我们将研究各种环境下的性…

XML——文档类型定义(DTD-Document Type Definition)

【0】README 0.1)本文文字描述转自 core java volume 2 , 旨在理解 XML——文档类型定义(DTD-Document Type Definition) 的基础知识; 0.2) for source code, please visit https://github.com/pacosonTa…

职称计算机考试 数量,职称计算机考试WPS基础考点:自动求和

职称计算机考试WPS基础考点:自动求和导语:随着信息技术的发展,计算机日益走进人们的工作、学习和生活,成为专业技术人员不可或缺的工具。下面我们一起来看看职称计算机考试WPS的内容吧。1. 对不相邻单元格的数据求和假如要将单元格…

java静态导入

一、静态导入 在Java 5中,import语句得到了增强,以便提供甚至更加强大的减少击键次数功能,虽然一些人争议说这是以可读性为代价的。这种新的特性成为静态导入。当你想使用static成员时,可以使用静态导入(在API中的类和…

java流写入数据库_成为Java流大师–第4部分:数据库流

java流写入数据库SQL一直是一种声明性语言,而Java长期以来势在必行。 Java流改变了游戏规则。 通过本动手文章编写您的方式,并学习如何使用Java流对RDBMS数据库执行声明性查询,而无需编写任何SQL代码。 您会发现,Java流和SQL命令的…