您的位置:首页 > 其它

归并排序(合并排序)

2016-03-27 21:52 302 查看
合并排序(MERGE SORT)是又一类不同的排序方法,合并的含义就是将两个或两个以上的有序数据序列合并成一个新的有序数据序列,因此它又叫归并算法。它的基本思想就是假设数组A有N个元素,那么可以看成数组A是又N个有序的子序列组成,每个子序列的长度为1,然后再两两合并,得到了一个 N/2 个长度为2或1的有序子序列,再两两合并,如此重复,值得得到一个长度为N的有序数据序列为止,这种排序方法称为2—路合并排序。

  例如数组A有7个数据,分别是: 49 38 65 97 76 13 27,那么采用归并排序算法的操作过程如图7所示: 

  初始值 [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)
  归并算法如下:

#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}; //这里对8个元素进行排序  

    int low=0,high=6;                   //初始化low和high的值  

  

    printf("Before merge sort: ");  

    for(int i=low;i<=high;i++)  

    {  

        printf("%d ",a[i]);             //输出测试  

    }  

    printf("/n");  

  

    MergeSort(a,low,high);  

  

    printf("After merge sort:  ");  

    for( i=low;i<=high;i++)  

    {  

        printf("%d ",a[i]);             //输出测试  

    }  

    printf("/n");  

}   
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息