归并排序

         归并排序的思想是将大数组细分成一个个小数组(甚至可以使小数组只包含一个元素),然后对小数组不断进行归并,从而得到排好序的大数组。

         归并排序是基于比较的排序方式中的最优解,主要分为两种:自上而下和自底向上。两种排序方式的复杂度均为N*logN,较之初级排序方法的N^2大大提速,可以处理上百万个元素的数组,但是在解决小数组(元素数小于15)排序时,插入排序方法更快。

        两种归并排序方法的区别主要在于自上而下的归并需要调用递归,而自底向上的归并排序不需要,因此自底向上的方法适合对链表进行排序操作。

        以下为两种方式的代码:

void _merge(int *t, int lo, int mid, int hi)                     //将两个数组归并
{
    const int N = sizeof(t) / sizeof(t[0]);
    int tcpy[N];
    for(int i = lo; i <= hi; i++)                                //将数组复制到辅助数组中
        tcpy[i] = t[i];
    int left = lo, right = mid+1;                                //左边数组标记和右边数组标记
    for(int i = lo; i <= hi; i++)                                //向原数组中添加排列好的数据
    {
        if(left > mid) t[i] = tcpy[right++];                     //左边数组已空,添加右边数组数据
        else if(right > hi) t[i] = tcpy[left++];                 //右边数组已空,添加左边数组数据
        else if(tcpy[left] > tcpy[right]) t[i] = tcpy[right++];  //左边的大于右边的,添加右边
        else t[i] = tcpy[left++];                                //否则添加左边
    }
}

void top_down_mergesort(int *t, int lo, int hi)        //自上而下的归并排序(调用递归)
{
    if(lo >= hi)                                       //若子数组只剩一个元素,结束函数
        return;
    int mid = (lo+hi) / 2;                             //大数组分成两个小数组递归
    top_down_mergesort(t, lo, mid);
    top_down_mergesort(t, mid+1, hi);
    _merge(t, lo, mid, hi);                            //两个小数组归并成大数组
}

void bottom_up_mergesort(int *t, int lo, int hi)       //自底向上的归并排序(不需递归)
{
    int tlen = hi - lo + 1;                            //t的长度
    for(int sz = 1; sz < tlen; sz *= 2)                //每个子数组的长度变化
    {
        for(int i = 0; i < tlen - sz; i += (sz+sz))    //每一对要归并的数组的起始位置
        {
            int _hi;
            if(hi <= i + 2*sz -1)                      //判断边界
                _hi = hi;
            else
                _hi = i + 2*sz - 1;
            _merge(t, i, i+sz-1, _hi);                 //进行归并
        }
    }
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值