時間複雜度
《算法導論》2.3.1 分治法。
歸併排序採用了分治法的遞歸排序。分治法:分解子問題,解決子問題,合併子結果。
分解:分解待排序的 個元素的序列各成 個元素的子列。
解決:使用歸併排序遞å歸地排序兩個子序列。
合併:合併兩個已排序的子序列以產生已排序的答案。
因爲排序數組會被 拆開,歸併排序時間複雜度穩定的 。
相對於其它的 排序,它需要額外的臨時空間輔助,有一定的資源損耗。小數量級(百萬級別)的排序,要比快速排序慢。但是大數量級數據(千萬級別),因爲歸併排序樹深最小,排序比快速排序快。
快速排序,最優算法複雜度,數組會被 拆開。實際操作中數據很難達到最優。而歸併一直都是通過 進行拆分。
算法
算法導論實現思想
- 拆分左右兩個臨時數組,臨時數組最後是一個∞無窮大的數字。
- 兩個子數組進行比較,小的數值會拷貝到原數組。
實現
實際實現,通過一個輔助數組進行實現(源碼)。
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} 子數組最後一次合併排序流程。