排序——归并排序

归并排序利用分治法思想,通过二分法将问题分解为小规模子问题,然后逐步合并成原问题的解。其时间复杂度为O(N*lgN),空间复杂度为O(N),是一种稳定的排序算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.排序思路

归并排序可以用分治算法的思想来解决。
分治算法的基本思想:当我们求解某些问题时,由于这些问题要处理的数据相当多,或求解过程相当复杂,使得直接求解法在时间上相当长,或者根本无法直接求出。对于这类问题,我们往往先把它分解成几个子问题,找到求出这几个子问题的解法后,再找到合适的方法,把它们组合成求整个问题的解法。如果这些子问题还较大,难以解决,可以再把它们分成几个更小的子问题,以此类推,直至可以直接求出解为止。
分治法解题步骤:
(1)分解,将要解决的问题划分成若干规模较小的同类问题;
归并排序中,为使区间划分得简单和均匀,我们采用二分法来分解。
(2)求解,当子问题划分得足够小时,用较简单的方法解决;
(3)合并,按原问题的要求,将子问题的解逐层合并构成原问题的解。
借用一张图来说明归并排序的过程:
这里写图片描述
图片出处(http://blog.youkuaiyun.com/lemon_tree12138/article/details/51517753)

2.排序算法

void _Merge1(int *arr, int begin1, int end1, int begin2, int end2)
{
    int start = begin1;
    //开辟临时存储空间
    int *tmp = (int*)malloc(sizeof(int)*(end2 - begin1 + 1));
    int index = 0;
    while (begin1 <= end1 && begin2 <= end2)
    {
        if (arr[begin1] <= arr[begin2])
        {
            tmp[index++] = arr[begin1++];
        }
        if (arr[begin1] > arr[begin2])
        {
            tmp[index++] = arr[begin2++];
        }
    }
    while (begin1 <= end1)
    {
        tmp[index++] = arr[begin1++];
    }
    while (begin2 <= end2)
    {
        tmp[index++] = arr[begin2++];
    }
    //把数据从临时存储空间拷回原数组
    for (int i = 0; i < index; i++)
    {
        arr[start++] = tmp[i];
    }
    free(tmp);
}

void _MergeSort1(int *arr, int first, int last)
{
    if (first >= last)
        return;

    int mid = first + ((last - first) >> 1);
    _MergeSort1(arr, first, mid);
    _MergeSort1(arr, mid + 1, last);
    _Merge1(arr, first, mid, mid + 1, last);
}

void MergeSort1(int *arr, int size)
{
    if (arr == NULL)
        return;

    _MergeSort1(arr, 0, size - 1);
}

3.算法分析

由图可以看出,若子问题分解得足够均匀,是一种类似二叉树结构的处理方式,故归并排序的时间复杂度为O(N*lgN)。归并排序过程中,每一趟需要有一个辅助空间来暂存排序结果,但在该趟排序结束后立即释放空间,所以空间复杂度为O(N).
归并排序是一种稳定的排序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值