《算法導論》讀書筆記之排序算法—Merge Sort 歸併排序算法

自從打ACM以來也算是用歸併排序了很久,如今就寫一篇博客來介紹一下這個算法吧 :)html

 

  圖片來自維基百科,顯示了完整的歸併排序過程。例如數組{38, 27, 43, 3, 9, 82, 10}.ios

 

在算法導論講分治算法一章的時候提到了歸併排序。首先,歸併排序是一個分治算法。算法

歸併(Merge)排序法是將兩個(或兩個以上)有序表合併成一個新的有序表,數組

即把待排序序列分爲若干個有序的子序列,再把有序的子序列合併爲總體有序序列。函數

merg() 函數是用來合併兩個已有序的數組.  是整個算法的關鍵。spa

 

那麼歸併排序有什麼用處呢?code

  1. 對數組中元素經行排序
  2. 對鏈表中元素經行排序,其它排序算法如堆排序和快速排序不能對鏈表排序 (參考我寫的博客http://www.cnblogs.com/wushuaiyi/p/4558391.html)
  3. 能夠求逆序數 (參考我寫的博客http://www.cnblogs.com/wushuaiyi/p/4362149.html)
  4. 外排序 

 

下面是我寫的歸併排序使用C++實現的一個版本:htm

#include <iostream>

using namespace std;

const int MAXN = 10900;

int a[MAXN], tmp[MAXN], n;

void Merge (int l, int m, int r) {
    int i = l;
    int j = m + 1;
    int k = l;

    while (i <= m && j <= r) {
        if (a[i] < a[j]) {
            tmp[k++] = a[i++];
        } else {
            tmp[k++] = a[j++];
        }
    }

    while (i <= m) {
        tmp[k++] = a[i++];
    }
    while (j <= r) {
        tmp[k++] = a[j++];
    }

    for (int i = l; i <= r; ++i)
        a[i] = tmp[i];
}

void Merge_sort (int l, int r) {
    if (l < r) {
        int m = (l + r) >> 1;
        Merge_sort (l, m);
        Merge_sort (m + 1, r);
        Merge (l, m, r);
    }
}

int main() {
    std::ios::sync_with_stdio(false);
    int i, j, t, k, u, c, v, p, numCase = 0;

    while (cin >> n) {
        for (i = 0; i < n; ++i) {
            cin >> a[i];
        }
        Merge_sort(0, n - 1);

        for (i = 0; i < n; ++i) {
            cout << a[i] << endl;
        }
    }

    return 0;
}

 

歸併排序的效率是比較高的,設數列長爲N,將數列分開成小數列一共要logN步,blog

每步都是一個合併有序數列的過程,時間複雜度能夠記爲O(N),故一共爲O(N*logN)。排序

由於歸併排序每次都是在相鄰的數據中進行操做,

因此歸併排序在O(N*logN)的幾種排序方法(快速排序,歸併排序,希爾排序,堆排序)

也是效率比較高的。

相關文章
相關標籤/搜索