• 排序算法----归并排序


    归并排序完全遵循分治模式,主要操作分为三步:

    1.分解:分解待排序的n个元素序列为2个n/2个元素的子序列。

    2.解决:使用归并排序递归的排序两个子序列。

    3.合并:合并两个已排序的子序列。

    最重要的步骤就是合并2个已经排序的序列。例如:A和B都是从小到大排序的序列。依次对比A的第一个元素和B的第一个元素,把其中较小的元素出序列,插入到C中,直到两个序列中的元素都为空。最后,C序列就是一个包含A序列和B序列且从小到排序的序列。

     伪码:    

     1 Merge(A,p,q,r)
     2      n1 = q - p + 1
     3      n2 = r - q
     4      let L[1..n1 + 1]  and R[1.. n2 + 1] be new arrays
     5      for i = 1 to n1
     6           L[i] = A[p + i - 1]
     7      for j = 1 to n2
     8           R[i] = A[q + j]
     9     L[n1 + 1] =10     R[n2 + 1] =11     i = 1
    12     j = 1
    13    for k = p to r
    14        if L[i] <= R[j] 
    15            A[k] = L[i]
    16            i = i + 1
    17         else
    18            A[k] = R[i]
    19            j = j + 1
    View Code

         上述伪码中,其中A为待排序的数组,且A[p..q ]和A[q + 1..r]都是排序好的。9,10行中,在L,R最后插入一个值,作为哨兵值,每当出现哨兵值时,它不可能为较小的值,这样可以简化代码,避免检查L或R为空。

     图例:

          

    最后我们使用Merge_sort 排序数组A[p...r]中的元素。若p >= r,时,数组中最多只有一个元素,所以是排序好的,程序结束;否则,分解数组A[p...r]为两个子数组A[p...q]和A[q + 1...r],然后合并2个子数组。

    伪码:   

    1 Merge_sort(A,p,r)
    2    if p < r
    3            q = ⌊(p + r) / 24            Merge_sort(A,p,q)
    5            Merge_sort(A,q + 1,r)
    6            Merge(A,p,q,r)
    View Code

    图例:

        

    归并排序的时间复杂度:T(n) = O(nlgn)

    C++代码:

     1 void Merge(int a[],int p,int q,int r)
     2 {
     3     int n1 = q - p + 1;
     4     int n2 = r - q;
     5 
     6     int *L = new int[n1],*R = new int [n2];
     7     for(int i = 0;i < n1;i++)
     8     {
     9         L[i] = a[p + i];
    10     }
    11     for(int i = 0;i < n2;i++)
    12     {
    13         R[i] = a[q + i + 1];
    14     }
    15 
    16     for(int k = p,iL = 0,iR = 0; k <= r;k++)
    17     {
    18         if(iL != n1 && iR == n2)
    19             a[k] = *L++;
    20         if(iR != n2 && iL == n1)
    21             a[k] = *R++;
    22 
    23         if(iL != n1 && iR != n2)
    24         {        
    25             if(*L < *R)
    26             {
    27                 a[k] = *L;
    28                 L++;
    29                 iL++;
    30             }
    31             else
    32             {
    33                 a[k] = *R;
    34                 R++;
    35                 iR++;
    36             }
    37         }
    38     }
    39     delete[] (L - n1);
    40     delete[] (R - n2);
    41 }
    42 
    43 //合并排序,T(n) = O(nlgn)
    44 void Merge_sort(int a[],int p,int r)
    45 {
    46     if(p < r)
    47     {
    48         int q = (p + r) / 2;
    49         Merge_sort(a,p,q);
    50         Merge_sort(a,q + 1,r);
    51         Merge(a,p,q,r);
    52     }
    53 }
    View Code
  • 相关阅读:
    将Ubuntu18.04安装到U盘,实现即插即用
    小技巧之 前端自适应
    web笔记之 环境搭建
    C++学习笔记之 单例模式
    推荐一款Markdown编辑器:typora
    C++学习笔记之 类和对象
    C++学习笔记之 函数
    C++学习笔记之 内联函数
    C++学习笔记之 引用
    C++学习笔记之 const
  • 原文地址:https://www.cnblogs.com/jx-dx/p/3759618.html
Copyright © 2020-2023  润新知