算法導論讀書筆記(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)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章