1. 程式人生 > >二叉堆及優先級隊列

二叉堆及優先級隊列

優先級 自底向上 鍵值 由於 ase 數據 二叉 ins err

數據結構既包括各數據存儲的方式和彼此間的關系結構,又含有“添加”、“取出”等對數據的操作,同時也帶有取出和添加數據時的規則。如隊列和棧就是以數據抵達的先後順序來形成這一規則的,但優先級隊列則是以數據內的鍵值作為基準來判斷誰先被取出。

二叉搜索樹(按照左子節點、父節點、右子節點的順序將鍵值由小到大排序)可實現優先級隊列,但是較復雜。而二叉堆的數據結構則較容易實現。二叉堆的邏輯結構是完成二叉樹,但可用以1為小標的一維數組表示。此外又可分為最大堆和最小堆。

由於二叉堆可用一維數組來表示,且根的小標為1。則設表示二叉堆的數組為A,二叉堆大小為H,那麽二叉堆的元素就存儲在A[1,...,H]中,當給定一個結點的小標i時,則可得到其父節點(i/2)、左子節點(2*i)、右子節點(2*i+1)。

1、使用給定數組生成最大堆的實現

// maxHeapify(A, i) 使以i為根結點的子樹成為最大堆看,設堆大小為H

maxHeapify(A, i)
    l = left(i) // 左子結點
    r = right(i) // 右子結點
    // 從左子結點、自身、右子節點中選出最大的結點
    largest = max{A[l], A[i], A[r]}的小標
    
    if largest != i     //i的子節點更大
        交換A[i] 與A[largest]
        maxHeapify(A, largest) //遞歸調用

  

// 通過自底向上地套用maxHeapify的方式,將數組A轉為最大堆

buildMaxheap(A)
    for i = H/2 downto 1
        maxHeapify(A, i)

  

優先級隊列中各個元素都包含鍵值,其存儲在數據集合S中,

insert(S, k):向集合S中插入元素k

extractMax(S): 從S中刪除鍵值最大的元素並返回鍵值

2、向優先級隊列中插入元素

// 更改優先級隊列中元素的鍵值
heapIncreaseKey(A, i, key)
    if key < A[i]
        error: 新鍵值小於當前鍵值
    A[i] = key
    while i >1 && A[parent(i)] < A[i]
        交換A[i] 和A[parent(i)]
        i = parent(i)

  

insert(key)
    H++
    A[H] = -INFTY
    heapIncreaseKey(A, H, key) //在A[H]中設置key值

  

3、獲取、刪除堆中最大元素

heapExtractMax(A)
    if H < 1
        error:
    max = A[1]
    A[1] = A[H]
    H--
    maxHeapify(A, 1)
    return max

  

二叉堆及優先級隊列