C语言:归并排序
归并排序(C语言)。
先上代码,理论会后面一起总结。
1. 递归
#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. 非递归
#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; }