『数据结构』斐波那契堆

1. 结构

斐波那契堆是一系列具有最小堆序的有根树的集合, 同一代(层)结点由双向循环链表链接, 为了便于删除最小结点, 还需要维持链表为升序, 即nd<=nd.right(nd==nd.right时只有一个结点或为 None), 父子之间都有指向对方的指针.

结点有degree 属性, 记录孩子的个数, mark 属性用来标记(为了满足势函数, 达到摊还需求的)

还有一个最小值指针 H.min 指向最小根结点


2. 势函数

下面用势函数来分析摊还代价, 如果你不明白, 可以看摊还分析

\Phi(H) = t(H) + 2m(h)
t 是根链表中树的数目,m(H) 表示被标记的结点数

最初没有结点

3. 最大度数

结点的最大度数(即孩子数)D(n)\leqslant \lfloor lgn \rfloor, 证明放在最后

4. 操作

4.1. 创建一个斐波那契堆

O(1)

4.2. 插入一个结点

nd = new node
nd.prt = nd.chd = None
if H.min is None:
    creat H with nd
    H.min = nd
else:
    insert nd into  H's root list
    if H.min<nd: H.min = nd
H.n +=1

\Delta \Phi = \Delta t(H) + 2\Delta m(H) = 1+0 = 1
摊还代价为O(1)

4.3. 寻找最小结点

直接用 H.min, O(1)

4.4. 合并两个斐波那契堆

def union(H1,H2):
    if H1.min ==None or (H1.min and H2.min and H1.min>H2.min):
        H1.min = H2.min
    link H2.rootList to H1.rootList 
    return H1

易知 \Delta \Phi = 0

4.5. 抽取最小值

抽取最小值, 一定是在根结点, 然后将此根结点的所有子树的根放在 根结点双向循环链表中, 之后还要进行树的合并. 以使每个根结点的度不同,

def extract-min(H):
    z = H.min
    if z!=None:
        for chd of z:
            link chd to H.rootList
            chd.prt = None
        remove z from the rootList of H
        if z==z.right:
            H.min = None
        else:
            H.min = z.right
            consolidate(H)
        H.n -=1
    return z

consolidate 函数使用一个 辅助数组degree来记录所有根结点(不超过lgn)对应的度数, degree[i] = nd 表示.有且只有一个结点 nd 的度数为 i.

def consolidate(H):
    initialize degree  with None
    for nd in H.rootList:
        d = nd.degree
        while degree[d] !=None:
            nd2 = degree[d]
            if nd2.degree < nd.degree:
                nd2,nd = nd,nd2

            make nd2 child of nd  
            nd.degree = d+1
            nd.mark = False # to balace the potential 

            remove nd2 from H.rootList
            degree[d] = None
            d+=1
        else: degree[d] = nd
    for i in degree:
        if i!=None: 
            link i to H.rootList
            if H.min ==None: H.min = i
            else if H.min>i: H.min = i

时间复杂度为O(lgn) 即数组移动的长度, 而最多有 lgn个元素

4.6. 关键字减值

def decrease-key(H,x,k):
    if k>x.key: error 
    x.key = k
    y=x.p
    if y!=None and x.key < y.key:
        cut(H,x,y)
        cascading-cut(H,y)
    if x.key < H.min.key:
      H.min = x
def cut(H,x,y):
    remove x from the child list of y, decrementing y.degree
    add x to H.rootList
    x.prt = None
     x.mark = False

def cascading-cut(H,y):
    z- y,prt
    if z !=None:
        if y.mark ==False:y.mark = True
        else:
            cut(H,y,z)
            cascading-cut(H,z)

4.7. 删除结点

decrease(H,nd, MIN)
extract-min(H)

最大度数的证明

这也是斐波那契这个名字的由来,
D(n)\leqslant \lfloor lgn \rfloor

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容

  • 0.目录 1.优先队列ADT 2.几种实现 3.二叉堆 4.d-堆 5.左式堆 6.斜堆 7.二项队列 8.斐波那...
    王侦阅读 3,047评论 1 2
  • 课程介绍 先修课:概率统计,程序设计实习,集合论与图论 后续课:算法分析与设计,编译原理,操作系统,数据库概论,人...
    ShellyWhen阅读 2,253评论 0 3
  • 目录 1.各种表的对比参考基本数据结构ADT及其实现1.1 三种表1.2 表的两种实现(数组、链表)之间的对比1....
    王侦阅读 15,228评论 0 11
  • 大部分内容来自于《大话数据结构》,代码全部使用Swift实现。至于为什么抽风写这个?😊你懂的。 1.线性表 线性表...
    一剑孤城阅读 81,773评论 12 111
  • “我在成人生活里创造稳定,俾使我的内在小孩感到安全。” 首先写下今天抽到的彩虹牌给我的提醒。 其实很多想对亲爱的说...
    张小凡Carrie阅读 632评论 1 0