排序算法系列-归并排序

2014-11-24 03:31:46 · 作者: · 浏览: 0

归并排序

Written By lpstudy, A man ofstriving for life.Please mark the deviation if you copy it.

1 排序描述

归并排序是一种重要的递归排序排序思想。它将一个大的问题划分成两个子问题,然后分别对两个小点的子问题进行求解,对求解后的结果合并后即为原大问题的解。由于这个是递归的,于是原来一个很大的问题,就被一点一点的拆分,最后拆分成最简单的情况,可以直接求解,然后将一点点的简单的情况逐个合并,最后即为所得。说着有些复杂,不过代码实现由于使用了递归,看起来就非常整洁明了了。

void MergeSort(整个A)
{
         if(满足条件)//这实际是递归的进行条件,也可以反过来看是递归的结束条件
         {
                  MergeSort(A的前一半);   //子问题,A的前一半
                  MergeSort(A的后一半);   //子问题,A的后一半
                  Merge(A的前一半,A的后一半);//两个子问题的解的合并
         }
}

2 存储结构

此排序算法可以直接数组存储。下面举例说明排序过程,一共有8个元素。

l 首先将8个元素的问题分解两个4个元素的问题。即9 2 83 和 7 1 0 6

l 然后对于前面4个的问题,即9 2 8 3,同样继续分解为两个2个元素的问题,即分解为92 和 8 3。

l 再次对于前面的小小子问题92,继续分解为两个子问题9和2

l 再再次对于前面的小小小子问题9,它只有一个元素,故而肯定是有序就不用排序了。

l 开始合并过程,将9和2两个子问题合并,排序成2,9;8和3两个子问题合并为3,8

l 继续合并2,9和3,8,合并成2,3,9,8.另外的一半同样合并为0,1,6,7

l 继续合并两个子问题得到最终的结果0,1,2,3,6,7,8,9

l 结果如下图所示

索引

0

1

2

3

4

5

6

7

元素值

9

2

8

3

7

1

0

6

第1趟

2

9

3

8

1

7

0

6

第2趟

2

3

8

9

0

1

6

7

第3趟

0

1

2

3

6

7

8

9

3 算法代码

主要分为两个部分,一个是总体递归框架部分,一个是对两个子问题的merge问题。

3.1 总体框架部分

//注意递归的结束条件,即只有一个元素的时候,递归截止

typedef int ElemType;

void MergeSort(ElemTypeA[],int low, int high)
{
    if(low 
  
   

3.2 合并函数

//两个子问题的合并问题。

void Merge(ElemType A[], int low,int mid, int high)
{
    //将两个有序表A[low-> mid]和A[mid+1 -> high] 合并。
    //需要借助第三个表帮助合并,为了简单起见,我直接定义一个局部静态数组充当暂存数据
    const int MAX_SIZE = 9999;
    static ElemType H[MAX_SIZE];//辅助合并表

    int m = mid++;
    int k = 0;//合并后的H表的索引

    while(low <=m && mid<= high)
    {
       if(A[low] 
    
     =0; --i,--high)
       A[high] =H[i];//将合并的集合复制回去
}

    

3.3 时间复杂度

由算法过程可以看出,每一个子问题合并为O(n)的级别,每一个子问题为T(n/2),故而中时间为T(n) = 2*T(n/2) + O(n)。这个时间复杂度为O(nlgn),而且它是一个稳定排序。

对于T(n) = a*T(n/b) + f(n)的形式,算法导论中有证明

如果f(n) <, 则T(n) = O()

如果f(n)=, 则T(n) = O(*lgn)

如果f(n)>, 则T(n) = O() 其中当n趋近于无穷时,a*f(n/b)/ f(n) < 1

举例来说:

T(n)= 2T(n/2) + O(1) 其中b=a=2,故而属于第1种情况,T(n) = O(n)

T(n)= 2T(n/2) + O(n) 其中b=a=2,故而属于第2种情况,T(n) = O(n*lgn)

T(n)= 2T(n/2) + O(n*n) 其中b=a=2,故而属于第3种情况,T(n) = O(n*n)

4 执行代码和截图

4.1 完整执行代码

#include 
    
     
using namespacestd;
 
typedef int ElemType;
 
//两个子问题的合并问题。
void Merge(ElemType A[], int low,int mid, int high)
{
    //将两个有序表A[low-> mid]和A[mid+1 -> high] 合并。
    //需要借助第三个表帮助合并,为了简单起见,我直接定义一个局部静态数组充当暂存数据

    const int MAX_SIZE = 9999;
    static ElemType H[MAX_SIZE];//辅助合并表
 
    int m = mid++;
    int k = 0;//合并后的H表的索引

    while(low <=m && mid<= high)
    {
       if(A[low] 
     
      =0; --i,--high) A[high] =H[i];//将合并的集合复制回去 } void MergeSort(ElemTypeA[],int low, int high) { if(low 
      
       

4.2 运行截图

\