归并排序
参考:
《linux c编程一站式学习》的例11.2
思想:
采取分而治之的策略:
1、divide: 把长度n的输入序列分成两个长度为n/2的序列
2、conquer: 对这两个序列分别采用归并序列
3、combine:将两个排序好的子序列合并成一个最终的排序序列
在描述归并排序的步骤时又调用了归并排序本身,可见这是一个递归的过程。
code:
1 #include <stdio.h> 2 3 #define LEN 8 4 5 int testData[LEN] = {5, 2, 4, 7, 1, 3, 2, 6}; 6 7 void merge(int start, int mid, int end) 8 { 9 int n1 = mid - start + 1; 10 int n2 = end - mid; 11 int left[LEN], right[LEN]; 12 int i, j, k; 13 for(i=0x00; i<n1; i++){//left holds a[start, mid] 14 left[i] = testData[start+i]; 15 } 16 for(j=0x00; j<n2; j++){//right holds a[mid+1, end] 17 right[j] = testData[mid+1+j]; 18 } 19 i = j = 0x00; 20 k = start; 21 while(i<n1 && j<n2){ 22 if(left[i] <= right[j]){ 23 testData[k++] = left[i++]; 24 }else{ 25 testData[k++] = right[j++]; 26 } 27 } 28 while(i < n1){//left[] is not exhausted; 29 testData[k++] = left[i++]; 30 } 31 while(j < n2){//right[] is not exhausted; 32 testData[k++] = right[j++]; 33 } 34 } 35 36 void sort(int start, int end) 37 { 38 int mid; 39 if(start < end){ 40 mid = (start + end) / 2; 41 printf("sort(%d-%d, %d-%d): %d, %d, %d, %d, %d, %d, %d, %d\n", 42 start, mid, mid+1, end, testData[0], testData[1], testData[2], 43 testData[3], testData[4], testData[5], testData[6], testData[7]); 44 sort(start, mid); 45 sort(mid+1, end); 46 merge(start, mid, end); 47 printf("merge(%d-%d, %d-%d) to: %d, %d, %d, %d, %d, %d, %d, %d\n", 48 start, mid, mid+1, end, testData[0], testData[1], testData[2], 49 testData[3], testData[4], testData[5], testData[6], testData[7]); 50 } 51 } 52 53 int main(int argc, char *argv[]) 54 { 55 sort(0, LEN-1); 56 return 0; 57 }
运行结果截图: