1. 程式人生 > >Python實現 《演算法導論 第三版》中的演算法 第6章 堆排序

Python實現 《演算法導論 第三版》中的演算法 第6章 堆排序

第6章 堆排序

1. 堆

堆是一個數組,它可以被看成一個近似的完全二叉樹。樹上的每一個結點對應陣列中的一個元素。除最底層外,該樹是完全充滿的,而且是從左向右填充。表示堆的陣列包括兩個屬性:A.length(通常)給出陣列元素的個數,A.heap-size表示有多少堆元素儲存在該陣列中。也就是說,雖然A[1…A.length]可能都存有資料,但只有A[1…A.heap-size]中存放的是堆的有效元素。這裡0<=A.heap-size<=A.length。

下面實現了書中的虛擬碼和練習題,包括:

  • P84:計算某一結點的父結點,左孩子和右孩子的下標見前三個函式。
  • P86:MAX-HEAPIFY
    ,該函式用於維護最大堆的性質,而且需要傳入引數heap_size。遞迴版本和迴圈版本分別見max_heapify_recursivemax_heapify_loop
  • P87:練習6.2-5用迴圈控制結構取代遞迴重寫MAX-HEAPIFY,見max_heapify_loop
  • P87:BUILD-MAX-HEAP,採用自底向上的方法利用過程MAX-HEAPIFY把一個大小為n=A.length的陣列A[1…n]轉換為最大堆,而且需要傳入引數heap_size
  • P89:HEAPSORT,堆排序演算法利用BUILD-MAX-HEAP將輸入陣列A[1…n]建成最大堆,其中n=A.length,見heap_sort
def get_parent(i):
    return (i-1) // 2


def get_left(i):
    return 2 * i + 1


def get_right(i):
    return 2 * i + 2


def max_heapify_recursive(A, heap_size, i):
    l = get_left(i)
    r = get_right(i)
    largest_ind = i
    if l < heap_size and A[l] > A[largest_ind]:
        largest_ind =
l if r < heap_size and A[r] > A[largest_ind]: largest_ind = r if largest_ind != i: A[i], A[largest_ind] = A[largest_ind], A[i] max_heapify_recursive(A, heap_size, largest_ind) def max_heapify_loop(A, heap_size, i): while i < heap_size: l = get_left(i) r = get_right(i) largest_ind = i if l < heap_size and A[l] > A[largest_ind]: largest_ind = l if r < heap_size and A[r] > A[largest_ind]: largest_ind = r if largest_ind == i: break else: A[i], A[largest_ind] = A[largest_ind], A[i] i = largest_ind def build_max_heap(A, heap_size): begin = len(A)//2 - 1 # len(A)//2 - 1是堆中第一個葉子節點的前一個節點 for i in range(begin, -1, -1): max_heapify_loop(A, heap_size, i) def heap_sort(A): heap_size = len(A) build_max_heap(A, heap_size) for i in range(len(A)-1, 0, -1): A[0], A[i] = A[i], A[0] heap_size -= 1 max_heapify_loop(A, heap_size, 0) def test(): A = [16, 4, 10, 14, 7, 9, 3, 2, 8, 1] # P86例子 max_heapify_recursive(A, len(A), 1) print(A) A = [16, 4, 10, 14, 7, 9, 3, 2, 8, 1] # P86例子 max_heapify_loop(A, len(A), 1) print(A) B = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7] # P88例子 build_max_heap(B, len(B)) print(B) C = [16, 14, 10, 8, 7, 9, 3, 2, 4, 1] # P89例子 heap_sort(C) print(C) if __name__ == '__main__': test()

2. 優先佇列