排序算法之 - 归并排序

    这一章节所讲的归并排序,跟希尔排序一样,也是一种效率很高的排序方法,也同样采用了分而治之的方法.
归并排序的基本思想为:先把无序序列一分为二,然后分别对两边的序列进行排序,最后再整合两边已经排好的序列.下边已一张图来展示归并排序的思想(图是借用网友的,见做的非常简洁易懂,便引用之)

从途中我们看到,二分后的两边序列,又进行二分归并处理,直到两边的序列不能二分为止.这就是采用的递归思想,出口为左右了;两边各只有一个元素,然后再将两边的有序序列归并成最终序列.下边看代码理解:
 

#include <iostream>
#include <string.h>
#include <errno.h>
#include <stdio.h>

using namespace std;

//需要注意的是,这里的类模板需要放在头文件中去实现,这里为了直观,直接放这里了
template <typename T>
class Sort
{
private:
//合并两边的有序序列
static void Merger(T* nArray, int nBegin, int nMid, int nEnd, bool Min2Max=true)
{
    int len = nEnd - nBegin + 1;
    T tmp[len];  //申请一个临时空间,存放合并后的序列
    int lIndex = nBegin; //左边有序序列的其实位置
    int rIndex = nMid + 1;//右边有序序列的起始位置
    int k = 0;  //临时空间的起始位置
    //分别从二分的左边第一个元素,右边的第一个元素开始比较,依次将二者的极值放到临时空间中
    while( (lIndex <= nMid)&&(rIndex <= nEnd))
    {
        if( Min2Max ? (nArray[lIndex] < nArray[rIndex]):(nArray[lIndex] > nArray[rIndex]))
        {
            tmp[k++] = nArray[lIndex++];
        }
        else
        {
            tmp[k++] = nArray[rIndex++];
        }
    }
    //把左边剩余的元素追加到临时空间中
    while(lIndex <= nMid)
    {
        tmp[k++] = nArray[lIndex++];
    }
    //或者把右边剩余的元素追加到临时空间中
    while(rIndex <= nEnd)
    {
        tmp[k++] = nArray[rIndex++];
    }
    //将临时空间排好序的元素放到原序列空间中
    for(int i=nBegin, k=0; i<=nEnd; i++)
    {
        nArray[i] = tmp[k++];
    }
}
//归并排序(注意采用的是递归方式)
static void Merger(T* nArray, int nBegin, int nEnd, bool Min2Max = true)
{
    if(nBegin != nEnd)
    {
        int Mid = (nEnd + nBegin)/2;  //将序列一分为二
        Merger(nArray, nBegin, Mid, Min2Max);//对左边的序列进行归并排序
        Merger(nArray, Mid+1, nEnd, Min2Max);//对右边的序列进行归并排序
        Merger(nArray, nBegin, Mid, nEnd, Min2Max); //合并左右两边已经排好序的序列
    }
}
public:
static void Merger(T* nArray, int nLen, bool Min2Max = true)
{
    Merger(nArray, 0, nLen-1, Min2Max);
}
};

int main(int argc, char* argv[])
{
    int array[] = {12,32,2,4,6,54,13,34,25,87,76,89,32,14,23};
    int len = sizeof(array)/sizeof(int);
    Sort<int>::Merger(array, len);
    for(int i=0; i<len; i++)
    {
        cout << array[i] << " ";
    }
    cout << endl;
    return 0;
}

编译测试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值