归并排序还是用到了递归(原来难理解的东西是因为递归),所以先不说递归就不会觉得难了。(额、、可惜已经说了,好吧,先当我没说= =)
那么先讨论一个问题:怎么把两个有序的数组合并成一个新的有序数组?
答:这个非常简单,只要从比较二个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数。然后再进行比较,如果有数列为空,那直接将另一个数列的数据依次取出即可。
(此答摘自我看懂的那个人的博客,为防止侵权这里贴上他的网址:http://blog.csdn.net/morewindows/article/details/6678165/)
那么知道怎么合并两个数组了,完全可以写一个函数实现合并一个数组的功能:
void mergearray(int *a,int left,int mid,int right,int *temp)
这个函数的功能是把a[left]~a[mid] 和a[mid+1]~a[right]这两个“数组”合并成一个数组,然后再取代原先这一块a数组的位置。其中temp这个临时空间是很有必要的。
代码如下:
1 void mergearray(int *a,int left,int mid,int right,int *temp) 2 { 3 int i,j,m,n,k; 4 i=left; 5 j=mid+1; 6 m=mid; 7 n=right; 8 k=0; 9 while (i<=m&&j<=n){ 10 if (a[i]<a[j]){ 11 k++; 12 temp[k]=a[i]; 13 i++; 14 } 15 else{ 16 k++; 17 temp[k]=a[j]; 18 j++; 19 } 20 } 21 while (i<=m){ 22 k++; 23 temp[k]=a[i]; 24 i++; 25 } 26 while (j<=n){ 27 k++; 28 temp[k]=a[j]; 29 j++; 30 } 31 for (i=1;i<=k;i++){ 32 a[left+i-1]=temp[i]; 33 } 34 }
好了,现在我们已经知道怎么合并有序了,重点要来了。怎么把数组变得有序呢?因为我们知道,要合并有序,前提先得有序啊!
答案我想你已经猜到了——递归。
我们不妨写一个函数来实现归并排序的功能 void mergesort(int *a,int left,int right,int *temp)
如果你看了我汉诺塔的那篇博客,现在应该会习惯我这样来说——
要想让一个数组有序void mergesort(int *a,int left,int right,int *temp),分为如下步骤:
第一步:让数组的前一半有序 void mergesort(a,left,mid,temp);
第二步:让数组的后一半有序 void mergesort(a,mid+1,right,temp);
第三步:合并两个有序的数组生成新的有序 void mergearray(a,left,mid,right,temp).
这样就完成了。是不是恍然大悟了呢~如果是,可以参考下面的C语言代码:
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 void mergearray(int *a,int left,int mid,int right,int *temp) 5 { 6 int i,j,m,n,k; 7 i=left; 8 j=mid+1; 9 m=mid; 10 n=right; 11 k=0; 12 while (i<=m&&j<=n){ 13 if (a[i]<a[j]){ 14 k++; 15 temp[k]=a[i]; 16 i++; 17 } 18 else{ 19 k++; 20 temp[k]=a[j]; 21 j++; 22 } 23 } 24 while (i<=m){ 25 k++; 26 temp[k]=a[i]; 27 i++; 28 } 29 while (j<=n){ 30 k++; 31 temp[k]=a[j]; 32 j++; 33 } 34 for (i=1;i<=k;i++){ 35 a[left+i-1]=temp[i]; 36 } 37 } 38 39 void mergesort(int *a,int left,int right,int *temp) 40 { 41 if (left<right) { 42 int mid=(left+right)/2; 43 mergesort(a,left,mid,temp); 44 mergesort(a,mid+1,right,temp); 45 mergearray(a,left,mid,right,temp); 46 } 47 } 48 49 int main() 50 { 51 int n; 52 scanf("%d",&n); 53 int *a=malloc(n*sizeof(int)); 54 int *p=malloc(n*sizeof(int)); 55 int i; 56 for (i=1;i<=n;i++){ 57 scanf("%d",a+i); 58 } 59 mergesort(a,1,n,p); 60 for (i=1;i<=n;i++){ 61 printf("%d:%d\n",i,a[i]); 62 } 63 free(a); 64 free(p); 65 return 0; 66 }