007.归并排序(Merge Sort)

基本思想:

归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。

归并排序示例:

 


合并方法:

设r[i…n]由两个有序子表r[i…m]和r[m+1…n]组成,两个子表长度分别为n-i +1、n-m

  1. j=m+1;k=i;i=i; //置两个子表的起始下标及辅助数组的起始下标
  2. 若i>m 或j>n,转⑷ //其中一个子表已合并完,比较选取结束
  3. //选取r[i]和r[j]较小的存入辅助数组rf
    如果r[i]<r[j],rf[k]=r[i]; i++; k++; 转⑵
    否则,rf[k]=r[j]; j++; k++; 转⑵
  4. //将尚未处理完的子表中元素存入rf
    如果i<=m,将r[i…m]存入rf[k…n] //前一子表非空
    如果j<=n ,  将r[j…n] 存入rf[k…n] //后一子表非空
  5. 合并结束。
    1. //将r[i…m]和r[m +1 …n]归并到辅助数组rf[i…n]  
    2. void Merge(ElemType *r,ElemType *rf, int i, int m, int n)  
    3. {  
    4.     int j,k;  
    5.     for(j=m+1,k=i; i<=m && j <=n ; ++k){  
    6.         if(r[j] < r[i]) rf[k] = r[j++];  
    7.         else rf[k] = r[i++];  
    8.     }  
    9.     while(i <= m)  rf[k++] = r[i++];  
    10.     while(j <= n)  rf[k++] = r[j++];  
    11. }  

    归并的迭代算法


    1 个元素的表总是有序的。所以对n 个元素的待排序列,每个元素可看成1 个有序子表。对子表两两合并生成n/2个子表,所得子表除最后一个子表长度可能为1 外,其余子表长度均为2。再进行两两合并,直到生成n 个元素按关键码有序的表。

    1. void print(int a[], int n){  
    2.     for(int j= 0; j<n; j++){  
    3.         cout<<a[j] <<"  ";  
    4.     }  
    5.     cout<<endl;  
    6. }  
    7.   
    8. //将r[i…m]和r[m +1 …n]归并到辅助数组rf[i…n]  
    9. void Merge(ElemType *r,ElemType *rf, int i, int m, int n)  
    10. {  
    11.     int j,k;  
    12.     for(j=m+1,k=i; i<=m && j <=n ; ++k){  
    13.         if(r[j] < r[i]) rf[k] = r[j++];  
    14.         else rf[k] = r[i++];  
    15.     }  
    16.     while(i <= m)  rf[k++] = r[i++];  
    17.     while(j <= n)  rf[k++] = r[j++];  
    18.     print(rf,n+1);  
    19. }  
    20.   
    21. void MergeSort(ElemType *r, ElemType *rf, int lenght)  
    22. {   
    23.     int len = 1;  
    24.     ElemType *q = r ;  
    25.     ElemType *tmp ;  
    26.     while(len < lenght) {  
    27.         int s = len;  
    28.         len = 2 * s ;  
    29.         int i = 0;  
    30.         while(i+ len <lenght){  
    31.             Merge(q, rf,  i, i+ s-1, i+ len-1 ); //对等长的两个子表合并  
    32.             i = i+ len;  
    33.         }  
    34.         if(i + s < lenght){  
    35.             Merge(q, rf,  i, i+ s -1, lenght -1); //对不等长的两个子表合并  
    36.         }  
    37.         tmp = q; q = rf; rf = tmp; //交换q,rf,以保证下一趟归并时,仍从q 归并到rf  
    38.     }  
    39. }  
    40.   
    41.   
    42. int main(){  
    43.     int a[10] = {3,1,5,7,2,4,9,6,10,8};  
    44.     int b[10];  
    45.     MergeSort(a, b, 10);  
    46.     print(b,10);  
    47.     cout<<"结果:";  
    48.     print(a,10);  
    49.   
    50. }  
    两路归并的递归算法
    1. void MSort(ElemType *r, ElemType *rf,int s, int t)  
    2. {   
    3.     ElemType *rf2;  
    4.     if(s==t) r[s] = rf[s];  
    5.     else  
    6.     {   
    7.         int m=(s+t)/2;          /*平分*p 表*/  
    8.         MSort(r, rf2, s, m);        /*递归地将p[s…m]归并为有序的p2[s…m]*/  
    9.         MSort(r, rf2, m+1, t);      /*递归地将p[m+1…t]归并为有序的p2[m+1…t]*/  
    10.         Merge(rf2, rf, s, m+1,t);   /*将p2[s…m]和p2[m+1…t]归并到p1[s…t]*/  
    11.     }  
    12. }  
    13. void MergeSort_recursive(ElemType *r, ElemType *rf, int n)  
    14. {   /*对顺序表*p 作归并排序*/  
    15.     MSort(r, rf,0, n-1);  
    16. }  

猜你喜欢

转载自blog.csdn.net/qq_20398345/article/details/80917526
今日推荐