递归实现(函数递归调用) --自顶向下
1 /** 2 * Merge_Sort: 归并排序的递归实现 3 * 注:算法导论上给出的合并排序算法 4 * 递归过程是将待排序集合一分为二, 5 * 直至排序集合就剩下一个元素为止,然后不断的合并两个排好序的数组 6 * T(n) = O(nlgn) 7 **/ 8 #include <stdio.h> 9 #define LEN 8 10 11 // 合并 12 void merge(int a[], int start, int mid, int end) 13 { 14 int n1 = mid - start + 1; 15 int n2 = end - mid; 16 int left[n1], right[n2]; 17 int i, j, k; 18 19 for (i = 0; i < n1; i++) /* left holds a[start..mid] */ 20 left[i] = a[start+i]; 21 for (j = 0; j < n2; j++) /* right holds a[mid+1..end] */ 22 right[j] = a[mid+1+j]; 23 24 i = j = 0; 25 k = start; 26 while (i < n1 && j < n2) 27 if (left[i] < right[j]) 28 a[k++] = left[i++]; 29 else 30 a[k++] = right[j++]; 31 32 while (i < n1) /* left[] is not exhausted */ 33 a[k++] = left[i++]; 34 while (j < n2) /* right[] is not exhausted */ 35 a[k++] = right[j++]; 36 } 37 38 // merge_sort():先排序,再合并 39 void merge_sort(int a[], int start, int end) 40 { 41 int mid; 42 if (start < end) 43 { 44 mid = (start + end) / 2; 45 printf("sort (%d-%d, %d-%d) %d %d %d %d %d %d %d %d\n", 46 start, mid, mid+1, end, 47 a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]); 48 49 // 分解 + 解决:Divide + Conquer 50 merge_sort(a, start, mid); // 递归划分原数组左半边array[start...mid] 51 merge_sort(a, mid+1, end); // 递归划分array[mid+1...end] 52 // 合并:Combine 53 merge(a, start, mid, end); // 合并 54 55 printf("merge (%d-%d, %d-%d) to %d %d %d %d %d %d %d %d\n", 56 start, mid, mid+1, end, 57 a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]); 58 } 59 } 60 61 int main(void) 62 { 63 int a[LEN] = { 5, 2, 4, 7, 1, 3, 2, 6 }; 64 merge_sort(a, 0, LEN-1); 65 66 return 0; 67 }
非递归(迭代,循环展开)--自底向上
1 /** 2 * merge_sort: 非递归实现 --迭代 3 * 非递归思想: 将数组中的相邻元素两两配对。用merge函数将他们排序, 4 * 构成n/2组长度为2的排序好的子数组段,然后再将他们排序成长度为4的子数组段, 5 * 如此继续下去,直至整个数组排好序。 6 **/ 7 8 #include <stdio.h> 9 #include <stdlib.h> 10 #define LEN 8 11 12 // merge_sort(): 非递归实现-自底向上 13 // 将原数组划分为left[min...max] 和 right[min...max]两部分 14 void merge_sort(int *list, int length) 15 { 16 int i, left_min, left_max, right_min, right_max, next; 17 int *tmp = (int*)malloc(sizeof(int) * length); 18 19 if (tmp == NULL) 20 { 21 fputs("Error: out of memory\n", stderr); 22 abort(); 23 } 24 25 for (i = 1; i < length; i *= 2) // i为步长,1,2,4,8…… 26 { 27 for (left_min = 0; left_min < length - i; left_min = right_max) 28 { 29 right_min = left_max = left_min + i; 30 right_max = left_max + i; 31 32 if (right_max > length) 33 right_max = length; 34 35 next = 0; 36 while (left_min < left_max && right_min < right_max) 37 tmp[next++] = list[left_min] > list[right_min] ? list[right_min++] : list[left_min++]; 38 39 while (left_min < left_max) 40 list[--right_min] = list[--left_max]; 41 42 while (next > 0) 43 list[--right_min] = tmp[--next]; 44 } 45 } 46 47 free(tmp); 48 49 } 50 51 52 int main(void) 53 { 54 int a[LEN] = { 5, 2, 4, 7, 1, 3, 2, 6 }; 55 merge_sort(a, LEN); 56 57 // print array 58 int i; 59 for (i = 0; i < LEN; i++) 60 printf("%d ", a[i]); 61 62 return 0; 63 }