zoukankan      html  css  js  c++  java
  • 二路归并排序(也叫合并排序)

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

    二路归并的核心代码是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. }  
  • 相关阅读:
    拓扑排序
    Codeforces #503 C. Elections(贪心,逆向
    Codeforces #367 (Div. 2) D. Vasiliy's Multiset (trie 树)
    字典树
    最大子段和
    P1880 [NOI1995] 石子合并
    P1140 相似基因
    P1280 尼克的任务
    [BZOJ4064/Cerc2012]The Dragon and the knights
    [BZOJ4066]简单题
  • 原文地址:https://www.cnblogs.com/Ph-one/p/7359767.html
Copyright © 2011-2022 走看看