#排序算法#【5】合并排序

  ok,尘埃落定。期待工作的气息,越来越浓烈...继续更新博客,排序算法的最后一个——合并排序

  合并排序(Merge Sort)是将两个或多个有序表合并成一个有序表。也称为二路合并。

  合并排序的基本思想是:对于两个有续表合并初始时,把含有n个节点的待排序序列看做由n个长度为1的有序子表所组成麻将他们一次两两合并,得到长度为2的若干有序字表,再对这些字表进行两两合并,一直重复道长度为n,排序完成。

  数据示例如下:

  

  贴上代码:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #define ARRAYLEN 11
  4 //生成随机数
  5 int CreateData(int a[],int n,int min,int max){
  6     int i,j,flag;
  7 
  8     srand(time(NULL));
  9 
 10     if((max-min+1) < n) return -1;
 11 
 12     for(i = 0 ; i < n ; i++){
 13         do{
 14             a[i] = rand()%(max-min+1)+min;
 15             flag = 0;
 16             for(j = 0 ; j < i ; j++){
 17                 if(a[i] == a[j]){
 18                     flag = 1;
 19                     break;
 20                 }
 21             }
 22         }while(flag);
 23     }
 24 }
 25 
 26 //对两个数组进行合并
 27 void MergeStep(int a[],int r[], int s,int m,int e){
 28     int i,j,k;
 29     k = s;    //s之前的序号都是已排过序的,从s进行下一次合并
 30     i = s;    //第一个数组的开始序号
 31     j = m+1;  //第二个数组的开始序号
 32     while(i<= m && j <= e){
 33         if(a[i] <= a[j])
 34             r[k++] = a[i++];
 35         else
 36             r[k++] = a[j++];
 37     }
 38 
 39     while(i <= m)
 40         r[k++] = a[i++];
 41     while(j <= e)
 42         r[k++] = a[j++];
 43     
 44 }
 45 
 46 //控制需要合并的两个数组的序号
 47 void MergePass(int a[],int r[],int n,int len){
 48     int s,e,i;    //合并两个数组,第一个的起始序号,和结束序号,第二个数组对应的序号只需要+歩长值len即可
 49     s = 0;
 50     
 51     while(s+len < n){
 52         //保证至少有两个序列进行排序
 53         e = s+2*len -1;
 54         if(e >= n){    //第二个数组的结束序号
 55             e = n-1;
 56         }
 57 
 58         MergeStep(a,r,s,s+len-1,e);
 59 
 60         s = e+1;
 61     }
 62 
 63     //当不足两个序列时退出排序,这时将可能剩余的一个序列,直接放到r中
 64     if(s<n)
 65         for(;s<n;s++)
 66             r[s] = a[s];
 67 
 68 }
 69 
 70 
 71 //每次成倍增加歩长值进行合并
 72 void MergeSort(int a[],int n){
 73     int *p;    //分配一个和a一样大小的辅助数组空间
 74     int len = 1;    //歩长值
 75     int flag = 1;
 76     int i;
 77 
 78     if(!(p= (int *)malloc(sizeof(int)*n))){
 79         printf("内存分配失败!
");
 80         exit(0);
 81     }
 82 
 83     while(len < n){
 84         //再歩长值小于总长度的情况下,二路合并相邻的数组
 85         if(flag)    //交替两个数组,进行合并
 86             MergePass(a,p,n,len);
 87         else
 88             MergePass(p,a,n,len);
 89 
 90         len *= 2;    //歩长值每次增加一倍
 91         flag = 1-flag;
 92     }
 93 
 94     //当flag=1时,最终排序结果在p中,flag=0时,最终排序结果在a中
 95     //因此,当最后flag为1时,将最终结果在放到a中
 96     if(flag)
 97         for(flag = 0 ; flag < n ; flag++)
 98             a[flag] = p[flag];
 99     free(p);
100 }
101 
102 
103 int main(){
104     int i,a[ARRAYLEN];
105     /*for(i=0;i<ARRAYLEN;i++){
106         a[i] = 0;
107     }*/
108 
109     if(!CreateData(a,ARRAYLEN,1,100)){
110         printf("生成数据失败!
");
111         return -1;
112     }
113 
114     printf("原始数据:
");
115     for(i = 0 ; i < ARRAYLEN ; i++){
116         printf("%d ",a[i]);
117     }
118     
119     MergeSort(a,ARRAYLEN);
120 
121     printf("
排序后:
");
122     for(i = 0 ; i < ARRAYLEN ; i++){
123         printf("%d ",a[i]);
124     }
125     printf("
");
126 }
原文地址:https://www.cnblogs.com/fanchangfa/p/3849888.html