归并排序( merge sort )

一、简介

基本思想:归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。

最坏时间复杂度:O( NlogN )

最好时间复杂度:O( NlogN )

平均时间复杂度:O( NlogN )

二、归并排序操作

合并操作:取两个输入数组 A 和 B ( 两数组已排序 ),一个输出数组 C ,以及3个计数器 Actr , Bctr , Cctr , 它们初始置于对应数组的开始端。A[ Actr ] 和 B[ Bctr ] 中的较小者被复制到 C 中的下一个位置,相关的计数器向前推进一步。当两个输入表有一个用完的时候,则将另一个表中剩余部分复制到 C 中 。

代码:

/**
 * @description: 治 合并数组
 * @param {type} a 要排序数组 tmpArray 放置归并结果的数组
 *               leftPos 前半部分起始元素的下标 rightPos 后半部分起始元素的下标 
 *               rightEnd 后半部分末尾元素的下标
 * @return: null
 */
template < typename Comparable >
void merge( std::vector<Comparable> & a, std::vector<Comparable> & tmpArray,
            int leftPos, int rightPos, int rightEnd )
{
    int leftEnd = rightPos - 1;
    int tmpPos = leftPos;
    int numElements = rightEnd - leftPos + 1;

    // 主循环
    while( leftPos <= leftEnd && rightPos <= rightEnd )
        if( a[ leftPos ] <= a[ rightPos ] )
            tmpArray[ tmpPos++ ] = std::move( a[ leftPos++ ] );
        else
            tmpArray[ tmpPos++ ] = std::move( a[ rightPos++ ] );

    // 复制前半部分的剩余元素
    while( leftPos <= leftEnd )
        tmpArray[ tmpPos++ ] = a[ leftPos++ ];
    while( rightPos <= rightEnd )
        tmpArray[ tmpPos++ ] = a[ rightPos++ ];

    // 将tmpArray复制回原数组a
    for( int i = 0; i < numElements; ++i, --rightEnd )
        a[ rightEnd ] = std::move( tmpArray[ rightEnd ] );

}

递归操作:递归地将前半部分数据和后半部分数据各自归并排序,得到排序后的两部分数组,然后使用上面的合并算法再将这两部分合并到一起。

 

代码:

/**
 * @description: 分 
 * @param {type} a 要排序数组 tmpArray 放置归并结果的数组
 *               left 子数组最左边元素的下标 right 子数组最右边元素的下标 
 * @return: null
 */
template < typename Comparable >
void mergeSort( std::vector<Comparable> & a, std::vector<Comparable> & tmpArray,
                int left, int right )
{
    if( left < right )
    {
        int center = ( left + right ) / 2;
        mergeSort( a, tmpArray, left, center );
        mergeSort( a, tmpArray, center + 1, right );
        merge( a, tmpArray, left, center + 1, right );
    }
}

/**
 * @description: 归并排序
 * @param {type} a 要排序数组
 * @return: null
 */
template < typename Comparable >
void mergeSort( std::vector<Comparable> & a )
{
    std::vector< Comparable > tmpArray( a.size( ) );
    mergeSort( a, tmpArray, 0, a.size( ) - 1 );
}

三、代码实现

/*
 * @Author: lsyy
 * @Date: 2020-02-24 10:41:45
 * @LastEditTime: 2020-02-24 16:53:18
 * @LastEditors: Please set LastEditors
 * @Description: 归并排序
 * @FilePath: \merge sort\Src\main.cpp
 */



#include <iostream>
#include <string>
#include <functional>
#include <queue>
#include <vector>


/**
 * @description: 治 合并数组
 * @param {type} a 要排序数组 tmpArray 放置归并结果的数组
 *               leftPos 前半部分起始元素的下标 rightPos 后半部分起始元素的下标 
 *               rightEnd 后半部分末尾元素的下标
 * @return: null
 */
template < typename Comparable >
void merge( std::vector<Comparable> & a, std::vector<Comparable> & tmpArray,
            int leftPos, int rightPos, int rightEnd )
{
    int leftEnd = rightPos - 1;
    int tmpPos = leftPos;
    int numElements = rightEnd - leftPos + 1;

    // 主循环
    while( leftPos <= leftEnd && rightPos <= rightEnd )
        if( a[ leftPos ] <= a[ rightPos ] )
            tmpArray[ tmpPos++ ] = std::move( a[ leftPos++ ] );
        else
            tmpArray[ tmpPos++ ] = std::move( a[ rightPos++ ] );

    // 复制前半部分的剩余元素
    while( leftPos <= leftEnd )
        tmpArray[ tmpPos++ ] = a[ leftPos++ ];
    while( rightPos <= rightEnd )
        tmpArray[ tmpPos++ ] = a[ rightPos++ ];

    // 将tmpArray复制回原数组a
    for( int i = 0; i < numElements; ++i, --rightEnd )
        a[ rightEnd ] = std::move( tmpArray[ rightEnd ] );

}
/**
 * @description: 分 
 * @param {type} a 要排序数组 tmpArray 放置归并结果的数组
 *               left 子数组最左边元素的下标 right 子数组最右边元素的下标 
 * @return: null
 */
template < typename Comparable >
void mergeSort( std::vector<Comparable> & a, std::vector<Comparable> & tmpArray,
                int left, int right )
{
    if( left < right )
    {
        int center = ( left + right ) / 2;
        mergeSort( a, tmpArray, left, center );
        mergeSort( a, tmpArray, center + 1, right );
        merge( a, tmpArray, left, center + 1, right );
    }
}

/**
 * @description: 归并排序
 * @param {type} a 要排序数组
 * @return: null
 */
template < typename Comparable >
void mergeSort( std::vector<Comparable> & a )
{
    std::vector< Comparable > tmpArray( a.size( ) );
    mergeSort( a, tmpArray, 0, a.size( ) - 1 );
}

int main( )
{
    int a[] = {1,8,7,5,90,8,4,2,7,6};
    std::vector<int> iv(a,a+sizeof(a)/sizeof(int));

    mergeSort( iv );



    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值