算法导论读书笔记(19)斐波那契堆

第五部分 高级数据结构

第19章 斐波那契堆

两种用途:
1. 支持一系列操作,这些操作构成了所谓的“可合并堆”;
2. 这些操作可以在常数摊还时间内完成,使得非常适合于需要频繁调用这些操作的应用;
这里写图片描述

1. 斐波那契堆结构

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

每个结点x包含一个指向它父结点的指针x.p和一个指向它的某一个孩子的指针x.childx的所有孩子被链接成一个环形的双向链表,称为x的孩子链表。孩子链表中的每个孩子y均有指针y.left和y.right,分别指向y的左兄弟和右兄弟。如果y是仅有的一个孩子,则y.left = y.right =y

结点x的孩子链表中的孩子数目储存在x.degree。布尔值属性x.mark指示结点x自从上一次成为另一个结点的孩子后,是否失去过孩子

通过指针H.min来访问一个给定的斐波那契堆H,该指针指向具有最小关键字的树的根结点,我们把这个结点称为斐波那契堆的最小结点

如果一个斐波那契堆H是空的,那个H.min为NIL

H.n表示H中当前的结点数目
这里写图片描述

势函数

t(H)表示H中根链表中树的数目,m(H)表示H中已标记的结点数目。H的势函数如想:
Φ(H) = t(H) + 2m(H)

2. 可合并堆操作

创建一个新的斐波那契堆

创建一个空的H,Make-Fib-Heap分配并返回一个Fib对象H,其中H.n = 0和H.min = NIL,H中不存在树。
因为 t(H) =0和m(H) =0,Φ(H) = 0。因此,Make-Fib-Heap的摊还代价等于它的实际代价O(1)

插入一个结点

这里写图片描述

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)
势的增加量为: ( t(H) + 1 + 2m(H)) - ( t(H) + 2m(H)) = 1
实际代价为O(1),因此摊还代价为O(1) + 1 = O(1)

寻找最小结点

最小结点可通过H.min得到。因此,可以在O(1)的实际代价内找到最小结点。H的势没有发生变化,因此该操作的摊还代价等于它的初阶代价O(1)。

两个斐波那契堆的合并

将H1和H2的根链表链接,然后确定新的最小结点。之后,销毁H1和H2,表示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

势函数变化为:
Φ(H) - (Φ(H1)+Φ(H2)) = (t(H)+2m(H)) - ((t(H1)+2m(H1)) + (t(H2)+2m(H2))) = 0
摊还代价等于它的实际代价O(1)

抽取最小结点

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

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
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(lgn)

3.关键字减值和删除一个结点

这里写图片描述
这里写图片描述

Fib-Heap-Decrease-Key(H, x, k)
    if k > x.key
        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 = y.p
    if z != NIL
        if y.mark = FALSE
            y.makr = TRUE
        else
            Cut(H, y, z)
            Cascading-Cut(H, z)

摊还时间为O(1)

4. 删除一个结点

Fib-Heap-Delete(H, x)
    Fib-Heap-Decrease-Key(H, x, -∞)
    Fib-Heap-Extract-Min(H)

摊还时间为O(lgn)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值