二路归并排序(也叫合并排序)

Posted 柒月

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二路归并排序(也叫合并排序)相关的知识,希望对你有一定的参考价值。

下面这图展示了二路归并的过程

技术分享

二路归并的核心代码是merge()函数

它将2个分割的数组有序的合并在一起

如图:

在数组A中,

从p到q是一个数组,从q到r是另外一个数组

那么如何将这2个数组有序的合并在一起,组个新的数组A呢?

步骤:

第一步:开辟一个数组L,存放p到q之间(也就是需要归并的左边数组)的元素

第二部:开辟一个数组R,存放q到r之间(也就是需要归并的右边数组)的元素

第三步:2个数组的最后还要加一个无穷大的数(可以用0x7FFF表示),因此开辟的数组空间要多1字符个空间

第四步:L与R中的数字逐个比较,把较小的先放在数组A中(从数组A【0】开始存放,依次往后覆盖原来的数),然后较小的数组指针往后移动,指向下一位再和另外一个数组比较

 

技术分享

 

[cpp] view plain copy
 
  1. //第一个参数为需要排序的数组,第2个参数为分割的第一个数组开始元素的下标  
  2. //第3个参数为分割的第一个数组的最后1个元素的下标  
  3. //第4个参数为数组最后1个元素的下标  
  4. void Merge(int *A,int p,int q,int r)  
  5. {  
  6.     int n1,n2,i,j,k,g;  
  7.     n1=q-p+1;  
  8.     n2=r-q;  
  9.     int *L,*R;  
  10.     L=(int *)malloc(sizeof(int)*(n1+1));   
  11.     R=(int *)malloc(sizeof(int)*(n2+1));  
  12.     L[n1]=0x7fff; //开辟的左右2个数组最后1个数设置为最大值  
  13.     R[n2]=0x7fff;  
  14.     g=0;  
  15.     for(i=p;i<=q;i++)  
  16.     {  
  17.         L[g]=A[i];  
  18.         g++;  
  19.     }  
  20.     g=0;  
  21.     for(i=q+1;i<=r;i++)  
  22.     {  
  23.         R[g]=A[i];  
  24.         g++;  
  25.     }  
  26.     //逐个比较左右两组数组,把较小的值写入原来的数组  
  27.     j=k=0;  
  28.     for(i=p;i<=r;i++)  
  29.     {  
  30.         if(L[j]<R[k])  
  31.         {  
  32.             A[i]=L[j];  
  33.             j++;  
  34.         }  
  35.         else  
  36.         {  
  37.             A[i]=R[k];  
  38.             k++;  
  39.         }  
  40.     }  
  41. }  


完整代码:

 

 

[cpp] view plain copy
 
    1. #include<iostream>  
    2. using namespace std;  
    3.   
    4. //第一个参数为需要排序的数组,第2个参数为分割的第一个数组开始元素的下标  
    5. //第3个参数为分割的第一个数组的最后1个元素的下标  
    6. //第4个参数为数组最后1个元素的下标  
    7. void Merge(int *A,int p,int q,int r)  
    8. {  
    9.     int n1,n2,i,j,k,g;  
    10.     n1=q-p+1;  
    11.     n2=r-q;  
    12.     int *L,*R;  
    13.     L=(int *)malloc(sizeof(int)*(n1+1));   
    14.     R=(int *)malloc(sizeof(int)*(n2+1));  
    15.     L[n1]=0x7fff; //开辟的左右2个数组最后1个数设置为最大值  
    16.     R[n2]=0x7fff;  
    17.     g=0;  
    18.     for(i=p;i<=q;i++)  
    19.     {  
    20.         L[g]=A[i];  
    21.         g++;  
    22.     }  
    23.     g=0;  
    24.     for(i=q+1;i<=r;i++)  
    25.     {  
    26.         R[g]=A[i];  
    27.         g++;  
    28.     }  
    29.     //逐个比较左右两组数组,把较小的值写入原来的数组  
    30.     j=k=0;  
    31.     for(i=p;i<=r;i++)  
    32.     {  
    33.         if(L[j]<R[k])  
    34.         {  
    35.             A[i]=L[j];  
    36.             j++;  
    37.         }  
    38.         else  
    39.         {  
    40.             A[i]=R[k];  
    41.             k++;  
    42.         }  
    43.     }  
    44. }  
    45.   
    46. void MergeSort(int *A,int p,int r)  
    47. {  
    48.     int q;  
    49.     if(p<r) //当第一个元素比最后1个元素还小时,继续执行递归,直到只剩下一个元素(形参p=r)  
    50.     {  
    51.     q=(p+r)/2;  
    52.     MergeSort(A,p,q);  
    53.     MergeSort(A,q+1,r);  
    54.     Merge(A,p,q,r);  
    55.     }  
    56. }  
    57.   
    58. void main()  
    59. {  
    60.     int A[5]={5,3,4,23,11};  
    61.     MergeSort(A,0,4);  
    62.     for(int i=0;i<5;i++)  
    63.         cout<<A[i]<<endl;  
    64.     system("pause");  
    65. }  

以上是关于二路归并排序(也叫合并排序)的主要内容,如果未能解决你的问题,请参考以下文章

二路归并排序算法实现-完整C语言程序

排序算法——二路归并排序

二路归并排序java实现

归并排序法和基数排序法

排序算法:归并排序

二路归并排序算法