归并排序(看了别人的博客明白了也写个博客,希望这样不算抄袭~)

归并排序还是用到了递归(原来难理解的东西是因为递归),所以先不说递归就不会觉得难了。(额、、可惜已经说了,好吧,先当我没说= =)

  那么先讨论一个问题:怎么把两个有序的数组合并成一个新的有序数组?

答:这个非常简单,只要从比较二个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数。然后再进行比较,如果有数列为空,那直接将另一个数列的数据依次取出即可。

(此答摘自我看懂的那个人的博客,为防止侵权这里贴上他的网址: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
",i,a[i]);
62     }
63     free(a);
64     free(p);
65     return 0;
66 }
原文地址:https://www.cnblogs.com/itlqs/p/4769438.html