[排序算法]C++实现归并排序

基本思想

  归并排序是将两个或两个以上的有序表组合成一个新的有序表。
  假设初始序列有n个记录,则可看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到 n2 ⌈ n 2 ⌉ 个长度为2或1的有序子序列;再两两归并,……,如此重复,直至得到一个长度为n的有序序列为止,这种排序方法称为2-路归并排序。


实现快速排序的步骤

递归实现
1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置
3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
4. 重复步骤3直到某一指针到达序列尾
5. 将另一序列剩下的所有元素直接复制到合并序列尾
6. 将最终结果写回原数组

Tips:递归形式的算法在形式上较简洁,但实用性很差。


C++实现

void Merge(int arr[], int arrDst[], int iStart, int iEnd)
{
    if (iStart >= iEnd)
        return;
    int iMid = iStart + ((iEnd - iStart) >> 1);
    // 设定两个指针,最初位置分别为两个已经排序序列的起始位置
    int iStart1 = iStart, iEnd1 = iMid;
    int iStart2 = iMid + 1, iEnd2 = iEnd;
    Merge(arr, arrDst, iStart1, iEnd1);
    Merge(arr, arrDst, iStart2, iEnd2);
    int iIndex = iStart;

    // 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
    while (iStart1 <= iEnd1 && iStart2 <= iEnd2)
        arrDst[iIndex++] = arr[iStart1] < arr[iStart2] ? arr[iStart1++] : arr[iStart2++];

    // 将另一序列剩下的所有元素直接复制到合并序列尾
    while (iStart1 <= iEnd1)
        arrDst[iIndex++] = arr[iStart1++];
    while (iStart2 <= iEnd2)
        arrDst[iIndex++] = arr[iStart2++];
    // 将最终结果写回原数组
    for (iIndex = iStart; iIndex <= iEnd; iIndex++)
        arr[iIndex] = arrDst[iIndex];
}


void MergeSort(int arr[], const int iLength)
{
    // 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
    int *arrDst = new int[iLength];
    Merge(arr, arrDst, 0, iLength - 1);
    delete[]arrDst;
}

总结

  与快速排序、堆排序相比,归并排序最大的特点是,它是一种稳定的排序方法。但在一般情况下,很少利用2-路归并排序法进行内部排序

时间复杂度
   O(nlogn) O ( n l o g n )

空间复杂度
  实现归并排序需要和待排记录等数量的辅助空间。

最坏时间复杂度最优时间复杂度平均时间复杂度空间复杂度
O(nlogn) O ( n l o g n ) O(n) O ( n ) O(nlogn) O ( n l o g n ) O(n) O ( n )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值