码迷,mamicode.com
首页 > 编程语言 > 详细

归并排序(C语言实现)

时间:2017-11-18 11:05:48      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:失败   合并   mda   rect   malloc   typedef   es2017   申请   nlogn   

        合并排序(MERGE SORT)是又一类不同的排序方法,合并的含义就是将两个或两个以上的有序数据序列合并成一个新的有序数据序列,因此它又叫归并算法。

        它的基本思想就是假设数组A有N个元素,那么可以看成数组A是又N个有序的子序列组成,每个子序列的长度为1,然后再两两合并,得到了一个 N/2 个长度为2或1的有序子序列,再两两合并,如此重复,值得得到一个长度为N的有序数据序列为止,这种排序方法称为2—路合并排序。
  例如数组A有7个数据,分别是: 49 38 65 97 76 13 27,那么采用归并排序算法的操作过程: 
  初始值 [49] [38] [65] [97] [76] [13] [27] 
  看成由长度为1的7个子序列组成 
  第一次合并之后 [38 49] [65 97] [13 76] [27] 
  看成由长度为1或2的4个子序列组成 
  第二次合并之后 [38 49 65 97] [13 27 76] 
  看成由长度为4或3的2个子序列组成 
  第三次合并之后 [13 27 38 49 65 76 97] 
  合并算法的核心操作就是将一维数组中前后相邻的两个两个有序序列合并成一个有序序列。合并算法也可以采用递归算法来实现,形式上较为简单,但实用性很差。合并算法的合并次数是一个非常重要的量,根据计算当数组中有3到4个元素时,合并次数是2次,当有5到8个元素时,合并次数是3次,当有9到16个元素时,合并次数是4次,按照这一规律,当有N个子序列时可以推断出合并的次数是X(2 >=N,符合此条件的最小那个X)。
  其时间复杂度为:O(nlogn).所需辅助存储空间为:O(n)
  归并算法如下:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>   
typedef int RecType;//要排序元素类型  
void Merge(RecType *R, int low, int m, int high)
{
    //将两个有序的子文件R[low..m)和R[m+1..high]归并成一个有序的子文件R[low..high]  
    int i = low, j = m + 1, p = 0;                //置初始值  
    RecType *R1;                        //R1是局部向量  
    R1 = (RecType *)malloc((high - low + 1)*sizeof(RecType));
    if (!R1)
    {
        return;                         //申请空间失败  
    }

    while (i <= m&&j <= high)                //两子文件非空时取其小者输出到R1[p]上  
    {
        R1[p++] = (R[i] <= R[j]) ? R[i++] : R[j++];
    }

    while (i <= m)                         //若第1个子文件非空,则复制剩余记录到R1中  
    {
        R1[p++] = R[i++];
    }
    while (j <= high)                      //若第2个子文件非空,则复制剩余记录到R1中  
    {
        R1[p++] = R[j++];
    }

    for (p = 0, i = low; i <= high; p++, i++)
    {
        R[i] = R1[p];                     //归并完成后将结果复制回R[low..high]  
    }
}

void MergeSort(RecType R[], int low, int high)
{
    //用分治法对R[low..high]进行二路归并排序  
    int mid;
    if (low<high)
    {   //区间长度大于1   
        mid = (low + high) / 2;               //分解  
        MergeSort(R, low, mid);           //递归地对R[low..mid]排序  
        MergeSort(R, mid + 1, high);        //递归地对R[mid+1..high]排序  
        Merge(R, low, mid, high);          //组合,将两个有序区归并为一个有序区  
    }
}
void main()
{
    int a[7] = { 49, 38, 65, 97, 76, 13, 27 }; //这里对7个元素进行排序  
    int low = 0, high = 6;                   //初始化low和high的值  

    printf("Before merge sort: \n");
    for (int i = low; i <= high; i++)
    {
        printf("%d ", a[i]);             //输出测试  
    }
    printf("\n");

    MergeSort(a, low, high);

    printf("\n After merge sort: \n");
    for (int i = low; i <= high; i++)
    {
        printf("%d ", a[i]);             //输出测试  
    }
    printf("\n");
}

实现归并排序;归并排序算法分为两步,第一步:先将原来的数据表分成排好序的子表,然后调用 Merger  对子表进行归并,使之成为有序表,例如有如下向量:

  25,10,7,19,3,48,12,17,56,30,21

对此序列进行归并排序的步骤为:

技术分享图片

 

归并排序(C语言实现)

标签:失败   合并   mda   rect   malloc   typedef   es2017   申请   nlogn   

原文地址:http://www.cnblogs.com/qixinbo/p/7856012.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!