今天来谈谈排序效率较高的归并排序算法。web
思想:算法
分治 + 合并数组
具体点说就是将一个数组分红左右两个部分,而后将左右两个部分的顺序排好后,在合并到一块儿!测试
那么怎么将左右两个部分的顺序排好呢?spa
咱们这样看,用递归的思想,将左右两个部分再次分红各个的两个部分,直到每一个部分的数据个数为1。这样咱们便获得了有序的部分数组。指针
接着,咱们将这些数组合并。最终便会成为有序的数组。code
看代码:orm
1 /* 2 *归并排序 3 *丁洋 4 */ 5 #include<stdio.h> 6 #include<stdlib.h> 7 #include<malloc.h> 8 #include<time.h> 9 /* 10 *合并数组 11 *a[first --- mid-1] 12 *a[mid+1 --- last] 13 */ 14 void mergearray(int a[], int first, int mid, int last, int temp[]) 15 { 16 int i = first; 17 int j = mid + 1; 18 int n = last; 19 int m = mid; 20 int k=0; 21 while(i <= m && j <= n){ 22 if(a[i] <= a[j]){ 23 temp[k++] = a[i++]; 24 } 25 else{ 26 temp[k++] = a[j++]; 27 } 28 } 29 while(j <= n){/*右边还有数据*/ 30 temp[k++] = a[j++]; 31 } 32 33 while(i <= m){/*左边还有数据*/ 34 temp[k++] = a[i++]; 35 } 36 for(i=0;i<k;i++)/*注意此处的写法,从first开始*/ 37 a[first + i] = temp[i];/*合并排序后的数组*/ 38 } 39 /* 40 *将数组分为A,B两个部分 ,分治思想 41 */ 42 void merge_sort(int a[],int left,int right,int temp[]) 43 { 44 if(left < right) 45 { 46 int mid = (left + right) / 2; 47 merge_sort(a,left,mid,temp); /*A区有序*/ 48 merge_sort(a,mid + 1,right,temp); /*B区有序*/ 49 mergearray(a,left,mid,right,temp); /*合并AB区*/ 50 } 51 } 52 53 void sort(int a[],int n)/*使用一个临时指针*/ 54 { 55 int *p; 56 p = (int *)malloc(sizeof(int) * n); 57 merge_sort(a,0,n-1,p); 58 free(p); 59 } 60 61 int main() 62 { 63 int i; 64 int a[4] = {3,1,6,2}; 65 clock_t start, finish; 66 double duration; 67 /* 测量一个事件持续的时间*/ 68 start = clock(); 69 sort(a,4); 70 for(i=0;i<4;i++) 71 printf("%d ",a[i]); 72 // sleep(500); 73 finish = clock(); 74 duration = (double)(finish - start) / CLOCKS_PER_SEC; 75 printf( "\n%f seconds\n", duration ); 76 system("pause"); 77 }
测试结果时间显示为0,郁闷了,而后谷歌了一下,发现这是我时间精度的问题,在c语言中,最小也只能到毫秒级别的了。因此加上一个,sleep(500),呵呵,结果出来了,blog
在不少的时间复杂度为O(N*logN)的几种排序方法(快速排序,归并排序,希尔排序,堆排序),排序
归并排序效率仍是较高的。
下一节谈谈堆排序吧!