[算法導論]歸併排序

時間複雜度

《算法導論》2.3.1 分治法。

歸併排序採用了分治法的遞歸排序。分治法:分解子問題,解決子問題,合併子結果。

分解:分解待排序的 nn 個元素的序列各成 n2\frac{n}{2} 個元素的子列。

解決:使用歸併排序遞å歸地排序兩個子序列。

合併:合併兩個已排序的子序列以產生已排序的答案。

因爲排序數組會被 n2\frac{n}{2} 拆開,歸併排序時間複雜度穩定的 nlgnnlgn
算法深度

相對於其它的 nlgnnlgn 排序,它需要額外的臨時空間輔助,有一定的資源損耗。小數量級(百萬級別)的排序,要比快速排序慢。但是大數量級數據(千萬級別),因爲歸併排序樹深最小,排序比快速排序快。

快速排序,最優算法複雜度,數組會被 n2\frac{n}{2} 拆開。實際操作中數據很難達到最優。而歸併一直都是通過 n2\frac{n}{2} 進行拆分。


算法

算法導論實現思想

  1. 拆分左右兩個臨時數組,臨時數組最後是一個∞無窮大的數字。
  2. 兩個子數組進行比較,小的數值會拷貝到原數組。

算法
歸併


實現

實際實現,通過一個輔助數組進行實現(源碼)。

void merge_sort(int array[], int start, int mid, int end) {
    int k = 0;
    int low = start;
    int high = mid + 1;
    int* temp = (int*)malloc(sizeof(int) * (end - start + 1));
    
    while (low <= mid && high <= end) {
        (array[low] < array[high]) ? temp[k++] = array[low++]
                                   : temp[k++] = array[high++];
    }

    while (high <= end) temp[k++] = array[high++];
    while (low <= mid) temp[k++] = array[low++];
    for (int i = 0; i < k; i++) array[start + i] = temp[i];

    free(temp);
}

void merge(int array[], int start, int end) {
    if (start >= end) {
        return;
    }

    int mid = (start + end) / 2;
    merge(array, start, mid);
    merge(array, mid + 1, end);
    merge_sort(array, start, mid, end);
}

實現流程

數組 A = {5, 2,4,7, 1, 3, 2, 6} 子數組最後一次合併排序流程。
實現流程


參考

快速排序、歸併排序、堆排序三種算法性能比較

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