斐波那契堆(不太详尽)
总结:这一章讲了斐波那契堆,它是一种比二项堆更松散的堆,它由一组无序的二项树组成,对不涉及删除元素的操作,它仅需O(1)的平摊运行时间。本章介绍斐波那契堆的插入、合并、删除等操作。
1. 斐波那契堆的结构
每个结点x的域:
1) 父节点p[x]
2) 指向任一子女的指针child[x]
3) 左兄弟left[x]
4) 右兄弟right[x]
5) 子女的个数degree[x]
6) 布尔值域mark[x]
在斐波那契堆中,结点x的子女被链接成一个环形双链表,称为x的子女表。当left[x]=right[x]=x时,说明x是独子。
mark域记录了每个结点的一小段历史:
1) 在某个时刻,x是个根
2) 然后,x被链接到另一个结点上(CONSOLIDATE (FIB-HEAP-LINK) )
3) 再通过切断来去除x的两个子女(CUT, CASCADING-CUT)
一旦第二个孩子失掉了,x与其父节点之间的联系就被切断了,x成为一个新根。如果发生了第1步和第2步,且x的一个孩子被切割掉了,则mark[x]为TRUE。
在一个斐波那契堆中,所有树的根都通过用其left和right指针链接成一个环形的双链表,称为该堆的根表。min[H]指向根表中具有最小关键字的结点。n[H]代表H中目前包含的结点个数。
势函数:Φ(H) = t(H) + 2m(H),其中t(H)为根表中树的棵树,m(H)为H中有标记的结点的个数。
最大度数:结点最大度数的上界D(n)=O(lgn)
2. 可合并堆的操作
1)创建
MAKE-FIB-HEAP,分配并返回一个斐波那契堆对象H,且n[H]=0, min[H]=NIL。
实际代价:O(1)
势:Φ(H)=0
平摊代价:O(1)
2)插入
插入操作直接将结点插入根表中。
实际代价:O(1)
势的增加:(t(H)+1+2m(H))-(t(H)+2m(H))=1
平摊代价:O(1)+1=O(1)
伪代码
FIB-HEAP-INSERT(H,x)
degree[x] <- 0
p[x] <- NIL
child[x] <- NIL
left[x] <- x
right[x] <- x
mark[x] <- FALSE
concatenate the root list containing x with root list H
if min[H]=NIL or key[min[H]] > key[x]
then min[H] <- x
n[H] <- n[H]+1
3)寻找最小结点
min[H]指向最小结点
实际代价:O(1)
势的增加:0
平摊代价:O(1)
4)合并
直接将两个堆的根表并置,并确定新的min[H]
实际代价:O(1)
势的增加:0
平摊代价:O(1)
伪代码
FIB-HEAP-UNION(H1,H2)
H <- MAKE-FIB-HEAP()
min[H] <- min[H1]
concatenate the root list of H2 with the root list of H
if(min[H]=NIL or key[min[H1]]>key[min[H2]])
then min[H] <- min[H2]
n[H] <- n[H1]+n[H2]
free the objects H1 and H2
return H
5)抽取最小结点
先将最小结点的每个子女都成为一个根,然后将度数相同的根链接起来。注意,直到这里,才真正完成了根表中的树的合并。
实际代价:O(D(n)+t(H))
势的增加:至多(D(n)+1+2m(H))-(t(H)+2m(H))=D(n)-t(H)+1
平摊代价:O(D(n))=O(lgn)
伪代码
FIB-HEAP-EXTRACT-MIN(H)
z <- min[H]
if z!=NIL
then for each child x of z
do add x to the root list of H
p[x] <- NIL
remove z from the root list of H
if z=right[z]
then min[H] <- NIL
else min[H] <- right[z]
CONSOLIDATE(H)
n[H] <- n[H]-1
return z
CONSOLIDATE(H)将H根表中的度数相同的结点链接起来,直到根表中每个度数至多只有一个根。用到辅助数组A[0…D(n[H])],A[i]=y代表degree[y]=i
伪代码
CONSOLIDATE(H)
for i <- 0 to D(n[H])
do A[i] <- NIL
for each node w in the root list of H
do x <- w
d <- degree[x]
while A[d]!=NIL
do y <- A[d]
if key[y]<key[x]
then exchange y <-> x
FIB-HEAP-LINK(H,y,x)
A[d] <- NIL
d <- d+1
A[d] <- x
min[H] <- NIL
for i <- 0 to D(n[H])
do if A[i]!=NIL
then add A[i] to the root list of H
if min[H]=NIL or key[A[i]]<key[min[H]]
then min[H] <- A[i]
伪代码
FIB-HEAP-LINK(H,y,x)
remove y from the root list of H
make y a child of x, incrementing degree[x]
mark[y] <- FALSE
6)减小一个关键字
若结点的关键字减小后,关键字小于其父节点的关键字,则将此结点移出,置入根表中,另外,还需执行级联切断操作。
伪代码
FIB-HEAP-DECREASE-KEY(H,x,k)
if k > key[x]
then error “error”
key[x] <- k
y <- p[x]
if y!=NIL and key[x]<key[y]
then CUT(H,x,y)
CASCADING-CUT(H,y)
if key[x]<key[min[H]]
then min[H] <- x
伪代码
CUT(H,x,y)
remove x from the child list of y, decrementing degree[y]
add x to the root list of H
p[x] <- NIL
mark[x] <- FALSE
由于CUT使切断的结点的父节点y又失去了一个孩子,因此CASCADING-CUT判断父节点的MARK,若为FALSE,则由于y失去了一个孩子,设mark[y]为TRUE,若mark[y]已经为TRUE了,那么y已经失去了两个孩子了,那么继续切断y与p[y],再接着判断p[y]的MARK,一直沿树递归上去,直到找到一个根节点或未加标记的结点。
伪代码
CASCADING(H,y)
z <- p[y]
if z!=NIL
then if mark[y]=FALSE
then mark[y]=TRUE
else CUT(H,y,z)
CASCADING-CUT(H,z)
复杂度分析:
设递归调用了c次CASCADING()
实际代价:O(c)
势的变化:至多(t(H)+c+2(m(H)-c+2))-(t(H)+2m(H))=4-c (c-1个结点被级联切断消除标记,最后一次CASCADING-CUT可能给某个结点加上标记)
平摊代价:O(c)+4-c=O(1)
7)删除
平摊代价:O(lgn)
伪代码
FIB-HEAP-DELETE(H,x)
FIB-HEAP-DECREASE-KEY(H,x,-INF)
FIB-HEAP-EXTRACT-MIN(H)
斐波那契堆(不太详尽)相关推荐
- 优先队列——斐波那契堆(without source code)
[0]README 0.1) 本文部分内容转自 数据结构与算法分析,旨在理解 斐波那契堆 的基础知识: 0.2) 文本旨在理清 斐波那契堆的 核心idea,还没有写出源代码实现,表遗憾: 0.3)从实 ...
- 算法导论 第20章 斐波那契堆
斐波那契堆的定义 参看19章 二项堆我们可以看到对于可合并堆操作,二项堆均有O(lgn)的时间,对于本章将要讨论的斐波那契堆也支持这些操作,而且它有着更好的渐进时间界,对于不涉及元素删除的操作,它有着 ...
- 算法导论读书笔记-第十九章-斐波那契堆
算法导论第19章--斐波那契堆 可合并(最小)堆(mergeable min-heap) : 支持以下5种操作的一种数据结构, 其中每一个元素都有一个关键字: MAKE-HEAP(): 创建和返回一个 ...
- 算法导论之斐波那契堆
斐波那契堆,和二项堆类似,也是由一组最小堆有序的树构成.注意区别,不是二项树,是有根而无序的树.导论中,斐波那契堆只是具有理论上的意义,是以平摊分析为指导思想来设计的数据结构,主要是渐进时间界比二项堆 ...
- boost::graph模块实现斐波那契堆的测试程序
boost::graph模块实现斐波那契堆的测试程序 实现功能 C++实现代码 实现功能 boost::graph模块实现斐波那契堆的测试程序 C++实现代码 #include <boost/c ...
- 算法导论--斐波那契堆
斐波那契堆 斐波那契堆也是数据储存结构的一种,这种数据结构之所以产生,主要有两个优点:1.对于数据合并操作具有很高的效率:2.对于其他一般数据操作平均时间复杂度较好(注意这里是平均复杂度,不是最坏情形 ...
- 二项堆与斐波那契堆各个操作时间复杂度
过程 二项堆 斐波那契堆 MAKE_HEAP Θ(1) Θ(1) INSERT Ω(lgn) Θ(1) MINIMUM Ω(lgn) Θ(1) EXTRACT-MIN Θ(lgn) O(lgn) UN ...
- 《算法导论》第19章-斐波那契堆 引入 19.1 斐波那契堆结构
引入 1.可合并堆 可合并堆(mergeable heap)是支持以下5种操作: MAKE-HEAP():创建和返回一个新的不含任何元素的堆. INSERT(H,x):将一个已填人关键字的元素x插人堆 ...
- 《算法导论3rd第十九章》斐波那契堆
前言 第六章堆排序使用了普通的二叉堆性质.其基本操作性能相当好,但union性能相当差. 对于一些图算法问题,EXTRACT-MIN 和DELETE操作次数远远小于DECREASE-KEY.因此有了斐 ...
最新文章
- 学习笔记Spark(九)—— Spark MLlib应用(1)—— 机器学习简介、Spark MLlib简介
- python celery多worker、多队列、定时任务
- 自编码器深度分析+定制特征描述子构建初探
- linux内核配置与编译
- Flutter入门:application、module、package、plugin
- Git之添加公钥之后git clone ****提示sign_and_send_pubkey: signing failed: agent refused operation
- figma下载_如何在Figma中创建逼真的3D对象
- 急救WINDOWS内存错误
- 力扣 ---- java
- 如何实现一个文件系统
- 十分钟搞清字符集和字符编码
- 路由器和交换机哪个更好?路由器交换机怎么连接?
- Linux Capability探索实验
- Linux的文件夹是中文怎么用cd进入目录
- 一只兔子帮你理解 kNN
- Axue8.0基础使用篇
- php中文数组按拼音排序问题
- 编程培训怎么样 哪家编程培训机构靠谱
- SylixOS更新记录
- 同轴电缆技术参数(一)
热门文章
- hbase集群 数据写入_一种构建HBase集群全文索引方法,数据读取方法以及数据写入方法与流程...
- Lightgbm如何处理类别特征?
- OData的初步认识
- Struts1.x系列教程(1):用MyEclipse开发第一个Struts程序
- python -- 计算 平方,乘方,平方根
- 数据赋能 兴业惠民 | 山东省第三届数据应用创新创业大赛潍坊分赛场火热报名中
- 哔哩哔哩漫画-下载地址分析
- 【离散数学】集合与关系
- 每一个JAVA程序员都应该怀揣一个架构师的梦,这样你的职业发展前景一片大好...
- 项目感受|总结|献给怀揣着梦想来到兄弟连学习的兄弟姐妹们