zoukankan      html  css  js  c++  java
  • #排序算法#【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 }
  • 相关阅读:
    1 从瀑布到敏捷——漫画解读软件开发模式变迁史(转载)
    xshell 常用命令1
    Python---3基础输入方法
    React 初试
    Js 入门文档
    SpringCloud 入门知识篇
    SpringBoot mysql, redis 配置
    工作常用命令
    Java 内置锁 重入问题
    牛顿迭代法, 开根号
  • 原文地址:https://www.cnblogs.com/fanchangfa/p/3849888.html
Copyright © 2011-2022 走看看