算法学习之排序(6)--合并排序

一.算法描述

    归并排序将一个序列分成两个长度相等的子序列,为每一个子序列调用归并排序进行排序,然后再将它们合并成一个序列。合并两个子序列的过程称为归并,归并排序的运行时间并不依赖与输入数组中元素的组合方式。
    归并排序总是递归调用自己对子序列进行排序,递归退出的条件为数组中只包含一个元素时,函数不进行其他操作,直接返回。


二.时间复杂度

    归并排序每次都是将序列分成相等的两个子序列,因此,归并排序的时间复杂度与输入数组中的元素是否已经排序无关,在最好情况下,平均情况下和最差情况下的时间复杂度都为O(nlogn)。



三.空间复杂度

    归并排序的归并过程需要将两个子序列进行归并,如果是使用数组之类的结构存储数据的话,需要将两个子序列复制到额外的空间中,然后再进行归并,因此,使用数组作为存储结构的话,空间复杂度为O(n)。如果是使用的是链表作为数据的存储结构的化,那么两个子序列进行归并的过程只是将链表中的元素放到另外一个链表中,并不需要复制元素的值,空间复杂度为O(1)。



四.C++实现

#include <iostream>

#include "Sort.h"
#include "randomarray.h"

bool Merge(std::vector<int>::iterator Ite, int LeftIndex, int RightIndex)
{
    if (LeftIndex >= RightIndex)
    {
        return false;
    }

    if (LeftIndex == (RightIndex - 1))
    {
        return true;
    }


    int Mid = (LeftIndex + RightIndex) / 2;


    // copy the array
    std::vector<int> LeftArray;
    for (int Index = LeftIndex; Index < Mid; Index++)
    {
        int Tmp = *(Ite + Index);
        LeftArray.push_back(*(Ite + Index));
    }

    std::vector<int> RightArray;
    for (int Index = Mid; Index < RightIndex; Index++)
    {
        int Tmp = *(Ite + Index);
        RightArray.push_back(*(Ite + Index));
    }


    // merge the sub array
    for (int Index_left = 0, Index_right = 0, Index = LeftIndex;
    Index < RightIndex;
    Index++)
    {
        // Ended merge the left array
        if (Index_left >= LeftArray.size())
        {
            int Tmp = RightArray[Index_right];
            *(Ite + Index) = RightArray[Index_right++];
            continue;
        }

        // Ended merge the right array
        if (Index_right >= RightArray.size())
        {
            int Tmp = LeftArray[Index_left];
            *(Ite + Index) = LeftArray[Index_left++];
            continue;
        }

        // merge the two array
        if (RightArray[Index_right] > LeftArray[Index_left])
        {
            int Tmp = LeftArray[Index_left];
            *(Ite + Index) = LeftArray[Index_left++];
        }
        else
        {
            int Tmp = RightArray[Index_right];
            *(Ite + Index) = RightArray[Index_right++];
        }
    }

    return true;

}






bool MergeSort(std::vector<int>::iterator Ite, int LeftIndex, int RightIndex)
{
    // return false if the LeftIndex >= RightIndex
    if (LeftIndex >= RightIndex)
    {
        return false;
    }


    // return true when there are only one element in the array
    if (LeftIndex == (RightIndex - 1))
    {
        return true;
    }


    // split the array to two sub array
    int Mid = (LeftIndex + RightIndex) / 2;
    MergeSort(Ite, LeftIndex, Mid);
    MergeSort(Ite, Mid, RightIndex);

    // Merge the sub array
    return Merge(Ite, LeftIndex, RightIndex);

}


bool MergeSort(std::vector<int>& Array)
{
    int Size = Array.size();

    if (Size == 0)
    {
        return false;
    }

    if (Size == 1)
    {
        return true;
    }

    return MergeSort(Array.begin(), 0, Size);
}




五.参考文献

[1] Shaffer C A. Practical Introduction to Data Structure and Algorithm Analysis (C++ Edition)[J]. 2002.
[2] 科曼 and 金贵, 算法导论: 机械工业出版社, 2006.
[3] T. H. Cormen, C. E. Leiserson, R. L. Rivest, and C. Stein, "算法导论 (影印版)," ed: 北京: 高等教育出版社.






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值