標籤:排序 歸併排序
歸併排序
O(NlogN),所以歸併排序最壞情況能夠達到快速排序的平均水準
需要額外的儲存空間O(n)
1、對資料不斷的分割,直到剩下一個一個的
2、合并資料,在合并的時候,其實是兩個有序的數組,因此
這個過程是兩個有序數組進行合并排序
/<span id="_xhe_cursor"></span>/ 歸併排序// O(NlogN),所以歸併排序最壞情況能夠達到快速排序的平均水準// 需要額外的儲存空間O(n)// 1、對資料不斷的分割,直到剩下一個一個的// 2、合并資料,在合并的時候,其實是兩個有序的數組,因此// 這個過程是兩個有序數組進行合并排序#include "sort.h"// merge函數實現了合并的過程// i為數組最小索引,j為中間值,k為最大索引值int merge(void *data, int size, int esize, int i, int k, int j, int (*compare)(const void *key1, const void *key2)){int ipos, jpos, mpos;// i, j, m的遊標int *a = (int *)data;int *m;// 申請的m的額外空間if ((m = (int *)malloc(sizeof(int) * size)) == NULL){return -1;}memcpy(m, 0, sizeof(int) * size);ipos = i;jpos = j;// j為中間值mpos = 0;while (ipos <= j || jpos <= k){while (ipos <= j && jpos >= k)// 當就剩下i的索引沒有到中間{memcpy(&m[mpos], &a[ipos], sizeof(int));ipos++;mpos++;}while (ipos >= j && jpos <= k) // 當就剩下j的索引沒有到中間{memcpy(&m[mpos], &a[jpos], sizeof(int));jpos++;mpos++;}if (compare(&a[ipos], &a[jpos]) <= 0 )// 小的數先插入到m臨時序列{memcpy(&m[mpos], &a[ipos], sizeof(int));ipos++;mpos++;}else{memcpy(&m[mpos], &a[jpos], sizeof(int));jpos++;mpos++;}}data = m;// 返回data,此時已完成排序free(m);// 最後釋放mreturn 0;}// 排序函數int mgsort(void *data, int size, int esize, int i, int k, int (*compare)(const void *key1, const void *key2)){int j;if (i < k){j = (k + i - 1) / 2;// 讓j取中間值if (mgsort(data, size, esize, i, j, compare) < 0)// 不斷的分割左邊,遞迴後合并{return -1;} if (mgsort(data, size, esize, j+1, k, compare))// 分割右邊{return -1;}if (merge(data, size, esize, i, k, j, compare) < 0){return -1;}}return 0;}
演算法精解(三)——歸併排序