归并排序采用了分治法的思想,下面给出了非递归实现和递归实现的方法 ,以方便以后使用。
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 // begin: 左边子序列的起始下标 5 // mid : 右边子序列的起始下标 6 // end : 右边子序列的结束元素的下一个位置(子序列不包括end指向的元素) 7 void mergeArray(int a[], int begin, int mid, int end, int t[]) 8 { 9 int length = end - begin;// 合并后序列的长度 10 int i = begin, j = mid; // i,j分别指向两个子序列的开始位置 11 int k = 0; // 指示临时数组中下一个数据的写入位置 12 13 // 合并两个子序列元素 14 while (i < mid && j < end){ 15 if (a[i] <= a[j]){ 16 t[k++] = a[i++]; 17 }else{ 18 t[k++] = a[j++]; 19 } 20 } 21 // 如果还有没有合入的元素 22 while (i < mid){ 23 t[k++] = a[i++]; 24 } 25 26 while (j < end){ 27 t[k++] = a[j++]; 28 } 29 30 // 将合并结果重新写入到数组a中 31 for (i = 0; i < length; i++){ 32 a[begin + i] = t[i]; 33 } 34 } 35 36 void merge_sort(int a[], int left, int right) 37 { 38 int length = right - left + 1; 39 int *temp = (int*)malloc(length * sizeof(int));// 临时存放合并结果的数组 40 int i, step = 1; // 初始有序子序列步长设置为1 41 42 // 自底向上进行归并排序 43 while (step < length){ 44 for (i = 0; i+2*step < length; i += 2*step){ 45 mergeArray(a, i, i+step, i+2*step, temp); 46 } 47 48 if (i+step < length){ 49 mergeArray(a, i, i+step, right+1, temp); 50 } 51 52 step *= 2;// 子序列长度翻倍 53 } 54 55 free(temp); 56 } 57 58 void merge_sort_r(int a[], int left, int right, int t[]) 59 { 60 int mid; 61 if (left < right){ 62 // 注意,计算mid时很容易写成(right - left)/2可能出现mid<left的情况 63 mid = left + (right - left)/2; 64 merge_sort_r(a, left, mid, t); 65 merge_sort_r(a, mid+1, right, t); 66 mergeArray(a, left, mid+1, right+1, t); 67 } 68 } 69 70 int main() 71 { 72 int a[] = {7,2,11,5,8,3,4,7,10,9}; 73 int *temp = (int*)malloc(10 * sizeof(int)); 74 merge_sort_r(a, 0, 9, temp); 75 free(temp); 76 77 return 0; 78 }