歸併排序(C語言)。數組
先上代碼,理論會後面一塊兒總結。函數
1. 遞歸spa
#include <stdio.h> #include <stdlib.h> #include <string.h> /* 函數功能:合併 函數參數: arr: 目標數組 start: 待合併段開始下標 mid: 待合併段中間下標 end: 待合併段結束下標 */ void merge(int* arr, int start, int mid, int end) { int len_l, len_r; //左右待合併區間的長度 len_l = mid - start + 1; len_r = end - mid; int l[len_l], r[len_r]; //gcc, 兩個臨時數組,分別保存待合併的兩個區間 //int l[100], r[100]; //vc memcpy(l, arr + start, sizeof(int) * len_l); memcpy(r, arr + mid + 1, sizeof(int) * len_r); int i = 0, j = 0, k = start; while(i < len_l && j < len_r) { arr[k++] = l[i] < r[j] ? l[i++] : r[j++]; } while(i < len_l) { arr[k++] = l[i++]; } } /* 函數功能:歸併排序 函數參數: arr: 待排序的數組 start: 待排序數組開始下標 end: 待排序數組結束下標 */ void merge_sort(int* arr, int start, int end) { if(start < end) { int mid = (start + end) / 2; //歸 merge_sort(arr, start, mid); merge_sort(arr, mid + 1, end); //並 merge(arr, start, mid, end); } } int main() { int arr[11] = {-1, 2, 4, -12, 4, 0, 0, 12, 23, -4, 7000}; merge_sort(arr, 0, 10); for(int i = 0; i < 11; ++i) { printf("%d ", arr[i]); } printf("\n"); return 0; }
2. 非遞歸code
#include <stdio.h> #include <stdlib.h> #include <string.h> /* 函數功能:歸併排序 函數參數: arr: 待排序的數組 length: 該數組的長度 */ void merge_sort(int* arr, int length) { int step = 1; //歸併區間步長 int l[length], r[length]; //gcc, 兩個臨時數組,分別保存待歸併的兩個區間 //int l[100], r[100]; //vc while(step < length) { int start = 0; //歸併區間的開始下標 while(start < length - step) { //歸 int len_l, len_r; //左右待歸併區間的長度 len_l = len_r = step; memcpy(l, arr + start, sizeof(int) * len_l); if(start + 2 * step > length) { len_r = length - start - step; } memcpy(r, arr + start + step, sizeof(int) * len_r); //並 int i = 0, j = 0, k = start; while(i < len_l && j < len_r) { arr[k++] = l[i] < r[j] ? l[i++] : r[j++]; } while(i < len_l) { arr[k++] = l[i++]; } start += 2 * step; } step *= 2; } } int main() { int arr[11] = {-1, 2, 4, -12, 4, 0, 0, 12, 23, -4, 7000}; merge_sort(arr, 11); for(int i = 0; i < 11; ++i) { printf("%d ", arr[i]); } printf("\n"); return 0; }