算法學習與代碼實現5——堆排序

算法學習與代碼實現5——堆排序

堆排序的思想當年看《算法導論》看了好幾遍也沒理解,現在算是明白了。

算法思路

堆排序藉助的是堆這個數據結構。堆首先是個完全二叉樹,可以用數組表示。下面一張《算法導論》中的插圖形象的表示了二叉堆在數組中的表示:

這裏寫圖片描述

而最大堆又滿足一個額外的條件:

A[PARENT(i)] ≥A[i]

這樣,在堆排序中,我們需要首先將一個數組變成最大堆,然後將數組的第一個數和最後一個數互換,再將最後一個數從堆中排除,剩下的數再次進行這個過程,知道所有的數都從數組中派出,被排除的數就組成了一個排好序的序列。

算法性能

穩定性:不穩定

時間複雜度: O(nlogn)

空間複雜度:O(1)

僞代碼

堆排序有兩個輔助函數,一個是保持堆的性質,一個是建立最大堆。

保持堆的性質

MAX-HEAPIFY(A, i)
l <- LEFT(i)
r <- RIGHT(i)
if l ≤ heap-size[A] and A[l] > A[i]
    then largest <- l
    else largest <- i
if r ≤ heap-size[A] and A[r] > A[largest]
    then largest <- r
if largest ≠ i
    then exchange A[i] <-> A[largest]
         MAX-HEAPIFY(A, largest)

建立最大堆

BUILD-MAX-HEAP(A)
heap-size[A] <- length[A]
for i <- length[A]/2向下取整 downto 1
    do MAX-HEAPIFY(A, i)

堆排序

HEAPSORT(A)
BUILD-MAX-HEAP(A)
for i <- length[A] downto 2
    do exchange A[1] <->A[i]
       heap-size[A] <- heap-size[A] - 1
       MAX-HEAPIFY(A, 1)

C語言實現

堆排序對數組序號的使用比較多,因爲它完全就是使用數組的需要來表示數組中的元素在堆中的位置。相互關係也要用到序號。而《算法導論》中的介紹都是從序號1開始的,c語言實現中爲了避免不必要的麻煩,也從序號1開始。

保持堆的性質

#define LEFT(i)     (2 * i)
#define RIGHT(i)    (2 * i + 1)
void max_heapify(int * array, int node, int array_size){
    int heap_size = array_size;
    int l = LEFT(node);
    int r = RIGHT(node);
    int largest;
    if (l <= heap_size && array[l] > array[node]) {
        largest = l;
    }
    else {
        largest = node;
    }
    if (r <= heap_size && array[r] > array[largest]) {
        largest = r;
    }
    if (largest != node) {
        int tmp = array[node];
        array[node] = array[largest];
        array[largest] = tmp;
    }
    if (largest != node)
        max_heapify(array, largest, array_size);
}

建立最大堆

void build_max_heap(int * array, int array_size){
    for (int i = array_size/2; i >= 1; i--) {
        max_heapify(array, i, array_size);
    }
}

堆排序

void heap_sort(int * array, int array_size){
    build_max_heap(array, array_size);
    int heap_size = array_size;
    for (int i = array_size; i >= 2; i--) {
        int tmp = array[1];
        array[1] = array[i];
        array[i] = tmp;
        heap_size -= 1;
        max_heapify(array, 1, heap_size);
    }
}

本文代碼託管於:
https://github.com/haoranzeus/algorithms_study

發佈了51 篇原創文章 · 獲贊 2 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章