用支援遞迴的語言實現歸併排序是很簡單的。假設m_sort可以將一個數組排序,那麼m_sort的遞迴邏輯為:(m_sort的定義為void m_sort(void* arr, int left, int right))
基礎:當right<=left時,直接返回
歸納:求得left和right的中間值mid = (left + right) / 2,將m_sort作用於數組區間[left, mid]和[mid + 1, right],因為我們已經假設m_sort可以將數組排序,那麼經過兩次m_sort調用後,arr[left, mid]和arr[mid + 1, right]數組實際上已經變成了排序數組,之後,我們將這兩個排序數組歸併為一個排序數組。
遞迴排序的時間複雜度為:O(n*log(n)),與快速排序的時間複雜度是一樣的,並且它還是一種穩定的排序演算法。
參考代碼:
#include <stdio.h>#include <stdlib.h>#include <string.h>static void merge(void* arr, int(*cmp)(void*, void*), int left, int mid, int right, int size){ char* tmpArr = (char*)malloc((right - left + 1) * size); int i = left, j = mid + 1, k = 0; while (i <= mid && j <= right) { if (cmp((char*)arr + i * size, (char*)arr + j * size) <= 0) { memcpy(tmpArr + k * size, (char*)arr + i * size, size); k++;i++; } else { memcpy(tmpArr + k * size, (char*)arr + j * size, size); k++;j++; } } while (i <= mid) { memcpy(tmpArr + k * size, (char*)arr + i * size, size); k++;i++; } while (j <= right) { memcpy(tmpArr + k * size, (char*)arr + j * size, size); k++;j++; } for (i = 0; i < k; ++i) memcpy((char*)arr + (i + left) * size, tmpArr + i * size, size); free(tmpArr);}static void m_sort(void* arr, int(*cmp)(void*, void*), int left, int right, int size){ if (left >= right)return; int mid = (left + right) / 2; m_sort(arr, cmp, left, mid, size); m_sort(arr, cmp, mid + 1, right, size); merge(arr, cmp, left, mid, right, size);}void mergesort(void* arr, int n, int(*cmp)(void*, void*), int size){ m_sort(arr, cmp, 0, n - 1, size);}