《算法导论》第19章 斐波那契堆 个人笔记

第19章 斐波那契堆

19.1 斐波那契堆结构

斐波那契堆是一系列具有最小堆序的有根树的集合,棵树都遵循最小堆性质。

相关的属性:
1. x.p :结点x的父结点
2. x.child :指向结点x的某一个孩子的指针,x的所有孩子被链接成一个环形的双向链表,称为x的孩子链表
3. y.left,y.right :孩子链表中的每个孩子y的左兄弟和右兄弟。如果y是仅有的一个孩子,则 y.left=y.right=y
4. x.degree :结点x的孩子链表中的孩子数目
5. x.mark :指示结点x自从上一次成为另一个结点的孩子后,是否失去过孩子。新产生的结点是未被标记的,并且当结点x成为另一个结点的孩子时,它便成为未被标记结点
6. H.min :指向根链表中关键字最小的那个结点
7. H.n :表示H中当前的结点数目
8. t(H) :表示H中根链表中树的数目
9. m(H) :表示H中已标记的结点数目

势函数: Φ(H)=t(H)+2m(H)

19.2 可合并堆操作

  • 创建一个新的斐波那契堆
    MAKE-FIB-HEAP()过程分配并返回一个斐波那契堆对象H,其中 H..n=0,H.min=NIL 。实际代价为 O(1)
  • 插入一个结点:
    实际代价为 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.min得到,实际代价为 O(1)
  • 两个斐波那契堆的合并
    实际代价为 O(1)
FIB-HEAT-UNIN(H1, H2){
    H = MAKE-FIB-HEAP()
    H.min = H1.min
    concatenate the root list of H2 with the root list of H
    if (H.min == NIL)||(H2.min != NIL && H2.min.key < H1.min.key)
        H.min = H2.min
    H.n = H1.n + H2.n
    return H
}
  • 抽取最小结点:
    实际代价为 O(lgn)
FIB-HEAP-EXTRACT-MIN(H){
    z = H.min
    if z != NIL
        for each child 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 //z is the only one root of H
            H.min = NIL
        else
            H.min = z.right
            CONSOLIDATE(H)
        H.n--
    return z
}
//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 dagree as x
            if x.key > y.key
                exchange x with y
            FIB-HEAP-LINK(H,y,x)
            A[d]=NIL
            d++
        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 roott list
                    if A[i].key < H.min
                        H.min = A[i]
}
FIB-HEAP-LINK(H,y,x){
    remove y from the root list of H
    make y a child of x, increamentingg x.degree
    y.mark = FALSE
}

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

  • 关键字减值:
FIB-HEAP-DECREASE(H,x,k){
    if k > x.key
        error "new key is greater than current key"
    x.key = k
    y = x.p
    if y != NIL && x.key < y.key
        CUT(H,x,y)
        CASCADING-CUT(H,y)
    if x.key < H.min.key
        H.min= x
}
CUT(H,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.mark = TRUE
        else
            CUT(H,y)
            CASCADING-CUT(H,z)
}
  • 删除一个结点:
FIB-HEAP-DELECT(H,x){
    FIB-HEAP-DECREASE(H,x,-inf)
    FIB-HEAP-EXTRACT-MIN(H)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值