斐波那契堆

斐波那契堆——怎么发明一种非常聪明的数据结构——学习笔记 斐波那契堆从0开始,一步一步实现该数据结构,Java实现 阅读详情

斐波那契堆


作者: 大树先生
博客: http://blog.youkuaiyun.com/koala_tree
GitHub:https://github.com/koalatree
2017 年 09 月 13 日


自《算法导论》.

斐波那契堆有两种用途:第一种,支持一系列操作,这些操作构成了所谓的“可合并堆”。第二种,斐波那契堆的一些操作可以在常数摊还时间内完成。

可合并堆的两种实现方式下各操作的运行时间。在操作时堆中的项数用n表示。

这里写图片描述

一、斐波那契堆结构

一个斐波那契堆是一系列具有最小堆序的有根树的集合。也就是说,每棵树均遵循最小堆性质:每个结点的关键字大于或等于它的父结点的关键字。

这里写图片描述

结点属性:

  • x.p:指向其父结点的指针;
  • x.child:指向其某一个孩子结点的指针;x结点所有的孩子链接成一个环形双向链表,称为孩子链表;
  • y.left、y.right:每个孩子y包含,分别指向y的左兄弟和右兄弟,若只有一个孩子,则y.left=y.right=y;
  • x.degree:结点x的孩子链表中的孩子树木;
  • x.mark:结点x自从上一次成为另一个结点的孩子后,是否失去过孩子;
  • H.min:用来访问给定的斐波那契堆,指向具有最小关键字的树的根结点,称为最小结点;
  • H.n:表示H中当前结点数目。

势函数:

使用势方法来分析斐波那契堆操作的性能。

  • t(H) :表示H中跟链表中树的数目;
  • m(H) :表示H中已标记的结点数目;
  • 势函数 Φ(H) :
    Φ(H)=t(H)+2m(H)

最大度数:

在一个n个结点的斐波那契堆中任何结点的最大度数都有上界 D(n)⩽⌊lgn⌋ .

二、可合并堆操作

1. 创建一个新的斐波那契堆

过程分配并返回一个斐波那契堆对象H,其中H.n=0和H.min = NIL,H中不存在树。

由于 t(H)=0,m(H)=0 ,空斐波那契堆的势为 Φ(H)=0 ,因此创建新堆的摊还代价等于他的实际代价 O(1) 。

2. 插入一个结点

Fib_heap_insert(H, x)
    x.degree = 0
    x.p = NIL
    x.child = NIL
    x.mark = FALSE
    if H.min == NIL
        create a root list for H containing just x
        H.min = x
    else insert x into H's root list
        if x.key < H.min.key
            H.min = x
    H.n = H.n + 1

这里写图片描述

t(H′)=t(H)+1,m(H′)=m(H) ,则增加的势能为1,实际代价为 O(1) ,摊还代价为 O(1)+1=O(1) .

3. 寻找最小结点

通过指针H.min得到。可以在 O(1) 的实际代价内找到最小结点。

4. 两个斐波那契堆的合并

合并斐波那契堆 H1,H2 ,销毁这两个堆。

Fib_heap_union(H1, H2)
    H = Make_fib_heap()
    H.min = H1.min
    concatenate the root list of H2 with the root list of H
    if (H1.min == NIL) or (H2.min /= NIL and H2.min.key < H1.min.key)
        H.min = H2.min
    H.n = H1.n + H2.n
    return H

势函数变化为0,所以摊还代价等于实际代价 O(1) 。

5. 抽取最小结点

Fib_heap_extract_min(H)
    z = H.min
    if z /= NIL
        for each child x of z
            add x to the root list of H
            x.p = NIL
        remove z from the root list of H
        if z == z.right
            H.min = NIL
        else H.min = z.right
            Consolidate(H)
        H.n = H.n - 1
    return z

以上代码用到的合并(Consolidating)H根链表的操作,通过调用Consolidating(H)来减少斐波那契堆中树的数目。

过程重复执行以下步骤:

  • 在根链表中找到两个具有相同度数的根x和y,其中,x.key <= y.key;
  • 把y链接到x:从根链表中移除y,调用Fib_heap_link过程,使y称为x的孩子,该过程将x.degree属性增加1,并清除y上的标记。

使用辅助数组 A[0..D(H.n)] 记录根结点对应的度数的轨迹。如A[i] = y,那么当前的y是一个具有y.degree = i的根。

Consolidate(H)
    let A[0..D(H.n)] be a new array
    for i = 0 to D(H.n)
        A[i] = NIL
    for each node w in the root list of H
        x = w
        d = x.degree
        while A[d] /= NIL
            y = A[d]  #another node with the same degree as x
            if x.key > y.key
                exchange x with y
            Fib_heap_link(H, y, x)
            A[d] = NIL
            d = d + 1
        A[d] = x
    H.min = NIL
    for i = 0 to D(H.n)
        if A[i] /= NIL
            if H.min == NIL
                create a root list for H containing just A[i]
                H.min = A[i]
            else insert A[i] into H's root list
                if A[i].key < H.min.key
                    H.min = A[i]
Fib_heap_link(H, y, x)
    remove y from the root list of H
    make y a child of x, incrementing x.degree
    y.mark = FALSE

这里写图片描述

这里写图片描述

抽取最小结点的摊还代价为 O(D(n))=O(lgn) .

三、关键字减值和删除一个结点

1. 关键字减值

摊还时间: O(1) .

Fib_heap_decrease_key(H, x, k)
    error "new key is greater than current key"
    x.key = k
    y = x.p
    if y /= NIL and x.key < y.key
        Cut(H, x, y)
        Cascading_cut(H, y)
    if x.key < H.min.key
        H.min = x
Cut(H, x, y)
    remove x from the child list of y, decrementing y.degree
    add x to the root list of H
    x.p = NIL
    x.mark = FALSE
Cascading_cut(H, y)
    z = z.p
    if z /= NIL
        if y.mark == FALSE
            y.mark = TRUE
        else Cut(H, y, z)
            Cascading_cut(H, z)

斐波那契堆中规定,某个结点x一旦失掉第二个孩子,就切断x与其父结点的链接,是它称为一个新的跟。

所以,如果切掉的结点是其父结点的第二个孩子,则需要进行一次级联切断(cascading cut)。

过程示意图:

这里写图片描述

2. 删除一个结点

摊还时间: O(D(n))=O(lgn) .

Fib_heap_delete(H, x)
    Fib_heap_decrease_key(H, x, -inf)
    Fib_heap_extract_min(H)

O(1)+O(D(n))=O(D(n))=O(lgn) .

Dijkstra迪杰斯特拉算法 最短路径 Fibonacci Heap斐波那契堆实现以及与链表速度对比 比较懒,斐波那契堆只写了删除最小值和降低节点的值,但是也是最复杂的两个操作啦! In this assignment, there are three main parts in my code including the random directed graph generator, the dijkstra algorithm with list, and the dijkstra algorithm with Fibonacci Heap. The number of the node V is f 阅读详情

相关推荐

二项堆与斐波那契堆

二项堆 二项堆是符合最小堆性质的二项树链接成的森林二项树是形如下图的树

小虎 的博客 2098

斐波那契堆(Fibonacci heap)原理详解(附java代码实现)

前言   斐波那契堆(Fibonacci heap)是计算机科学中最小堆有序树的集合。它和二项式堆有类似的性质,但比二项式堆有更好的均摊时间。堆的名字来源于斐波那契数,它常用于分析运行时间。 堆结构介绍   基本术语介绍:   关键字:堆节点储存的用于比较的信息   度数:堆节点拥有的孩子数(注意,不包括孩子的孩子)   左兄弟:节点左边的兄弟节点 ...

weixin_30399871的博客 730

算法导论之斐波那契堆

斐波那契堆,和二项堆类似,也是由一组最小堆有序的树构成。注意区别,不是二项树,是有根而无序的树。导论中,斐波那契堆只是具有理论上的意义,是以平摊分析为指导思想来设计的数据结构,主要是渐进时间界比二项堆有改善。斐波那契堆除去删除元素操作外,其他操作只有O(1)的平摊运行时间,而二项堆需要O(lgn)的最坏情况运行时间。但若要斐波那契堆能转化为实际应用,除要保证有相同平摊时间界限外,还需更简单的数据结

医疗影像检索 4404

斐波那契堆(Fibonacci Heap)

也许我们每个人都知道斐波那契数列(Fibonacci sequence)。即这样一个数列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144...,如果我们用伪代码比表示: int FibonacciSequence(int n){ if (n == 1 || n == 2) { return 1; } return

yzf0011的专栏 4179

斐波那契堆(Fibonacci heaps)

canh

solar一抹阳光的专栏 6145

[Python] 斐波那契堆的实现

[Python] 斐波那契堆的实现斐波那契堆是一种基于堆的数据结构,其用途主要为: - 实现“可合并堆” -某些在斐波那契堆中常数摊还时间内完成的操作频繁使用的应用具体函数(操作):首先介绍堆中元素(节点)的实现: 元素初始化def __init__(self, key): self.key=key #关键字 self.degree=0 #元素在堆中的度

倒霉茄子的博客 1891

斐波那契堆的C++实现

本文改编自《算法导论》第三版第19章:斐波那契堆。

Castria的博客 3056

RV1106的ISP配置实战:MIPI与LVDS接口的硬件连接与设备树优化

本文详细解析了RV1106芯片的ISP配置实战,重点对比了MIPI CSI-2与LVDS两种主流接口的硬件连接方案与数据流差异。通过手把手的设备树代码示例,深入讲解了单路MIPI与双路LVDS摄像头的配置要点、关键属性设置及常见避坑指南,并提供了从驱动加载检查到Media Controller工具使用的系统化调试方法,帮助开发者快速打通图像采集与处理全链路。

terraform7cloud的博客 471

浅谈斐波那契堆

斐波那契堆是一种优先队列数据结构,具有较好的平摊时间复杂度,特别是在合并堆和减少键操作上表现优异。斐波那契堆的结构特点。它由一组最小堆有序的树组成,每棵树都是符合最小堆性质的,但不像二项堆那样严格的结构。每个节点有父指针、孩子链表,以及左右兄弟指针,这样形成一个环形双向链表。节点还需要记录度数、标记(mark)等属性。标记用于在删除节点时判断是否需要级联剪切,以保持结构的平衡。接下来,我们从数据结构、操作原理来大概讲一下。

eso1983的博客 1021

Sentaurus TCAD 实战指南:几何、掺杂与物理模型对Ion/Ioff的协同调控

本文详细介绍了Sentaurus TCAD在器件仿真中的实战应用,重点解析了Ion(开态电流)与Ioff(关态电流)的协同优化方法。通过几何结构设计、掺杂工程和物理模型选择三大要素的精细调整,实现器件性能的显著提升。文章结合28nm和7nm工艺案例,展示了如何平衡Ion与Ioff的矛盾关系,为TCAD工程师提供实用指导。

weixin_29159711的博客 135

从零实现Unitree Go2的SLAM建图与导航:手把手集成slam_toolbox和nav2(附Rviz2可视化配置)

本文详细指导如何在Unitree Go2四足机器人上集成slam_toolbox和nav2,实现SLAM建图与导航功能。从ROS2环境配置、雷达数据处理到slam_toolbox参数优化,再到nav2路径规划与Rviz2可视化调试,提供完整解决方案。特别适合机器人开发者快速掌握ROS2导航栈在Unitree Go2上的应用实践。

weixin_33737134的博客 1231

斐波那契堆为何称为斐波那契

本文只讨论斐波那契堆与斐波那契数列的关系,不对其增删改查做说明。(只是讨论) 废话一句: 斐波那契数列的递推公式:an=an-1+an-2 废话两句: 剪枝操作: 一个节点不能丢掉两个子节点,不然他也会被掉 树的合并: 两个同度数的树合并,取其中key值更小的根做为新树的根节点,偏大的根作为偏小的根的子节点 正文: 斐波那契堆由多个斐波那契树组成,符合斐波那契数列递推公式的是斐波那契树的最小节点数。记y阶斐波那契树为yd,其节点数为Nd,则有: Nd >= Nd...

qq_33956242的博客 417

【YOLOv8/v9/v10 实战 01】YOLOv8/v9/v10全系列实战对决:性能矩阵、架构拆解与2026部署指南

2026年YOLO生态已进入“战国时代”,Ultralytics YOLOv8/11/26、阿里YOLO12、清华YOLOv10、微软YOLOv9四大路线并行发展。本文基于官方文档、学术论文及实测数据,系统剖析三大核心版本(YOLOv8/v9/v10)的架构演进逻辑,构建覆盖参数量、mAP、FPS、FLOPs的完整性能矩阵。通过8组工业场景实测、全流程代码实现(训练-导出-部署)、6类硬件适配方案,解决新手选型难、进阶者优化无门、工业开发者部署低效的痛点。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 533

算法导论笔记:19斐波那契堆

可合并堆是支持以下5种操作的数据结构,其中每个元素都有一个关键字:        MAKE-HEAP():创建和返回一个新的不含任何元素的堆。        INSERT(H, x):将一个已填入关键字的元素x插入堆H中。        MINIMUM(H):返回一个指向堆H中具有最小关键字元素的指针。        EXTRACT-MIN(H):从堆H中删除最小关键字的元素,并返回指向该

程序员的自我修养 6274

《YOLO多模态创新改进专栏目录 》全网独家创新,多模态融合改进教程,包含早期融合、中期融合、后期融合、损失函数改进、二次创新模块、独家创新等几百种创新点改进,答疑群提供完整项目,永久更新中

🔥《YOLO多模态创新改进专栏》重磅来袭!🚀 本专栏汇集最新顶会顶刊创新点,提供1000+篇YOLO多模态改进方案(涵盖v8-v26),包含: 多模态融合策略(早期/中期/后期) 损失函数优化 独家创新模块 详细改进步骤 ✨特色服务: ✔️ 配套完整可运行项目 ✔️ 专业答疑群支持(含非计算机专业指导) ✔️ 持续更新至2026年 ✔️ 适用目标检测/OBB/分割/分类等多任务 💡适合人群: 科研人员 | 研究生 | 需发SCI/CCF论文者 环境要求宽松,新手友好,助力快速产出科研成果! 📈早订优

Ai缝合怪、助力小伙伴高效发论文 745

北斗导航 | raPPPid软件功能模块详解

raPPPid(Rapid Precise Point Positioning with integer ambiguity resolution,快速精密单点定位与整周模糊度解算)是由维也纳工业大学(TU Wien)大地测量与地理信息系开发的MATLAB开源PPP软件包。它是VieVS(Vienna VLBI and Satellite Software,维也纳VLBI与卫星软件)的PPP模块,由Marcus Franz Glaner和Robert Weber主导开发。

尘世冰封的专栏 585
上一篇: B树、B+树
下一篇: 迁移学习的TensorFlow实现
大树先生的博客
博客等级 码龄9年 2692粉丝 200原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值