归并排序算法原理分析与代码实现

  归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,归并排序将两个已排序的表合并成一个表。

    

归并排序基本原理

通过对若干个有序结点序列的归并来实现排序。

所谓归并是指将若干个已排好序的部分合并成一个有序的部分


归并排序基本思想

设两个有序的子序列(相当于输入序列)放在同一序列中相邻的位置上:array[low..m],array[m + 1..high],先将它们合并到一个局部的暂存序列 temp (相当于输出序列)中,待合并完成后将 temp 复制回 array[low..high]中,从而完成排序。

在具体的合并过程中,设置 i,j 和 p 三个指针,其初值分别指向这三个记录区的起始位置。合并时依次比较 array[i] 和 array[j] 的关键字,取关键字较小(或较大)的记录复制到 temp[p] 中,然后将被复制记录的指针 i 或 j 加 1,以及指向复制位置的指针 p加 1。重复这一过程直至两个输入的子序列有一个已全部复制完毕(不妨称其为空),此时将另一非空的子序列中剩余记录依次复制到 array 中即可。


若将两个有序表合并成一个有序表,称为2-路归并


举例说明"归并排序的排序过程"

看下面归并排序的两种排序过程

 1.待排序列(14,12,15,13,11,16)

假设我们有一个没有排好序的序列,那么首先我们使用分割的办法将这个序列分割成一个个已经排好序的子序列。然后再利用归并的方法将一个个的子序列合并成排序好的序列。分割和归并的过程可以看下面的图例。


                    

                  先"分割"再"合并"


从上图可以看出,我们首先把一个未排序的序列从中间分割成2部分,再把2部分分成4部分,依次分割下去,直到分割成一个一个的数据,再把这些数据两两归并到一起,使之有序,不停的归并,最后成为一个排好序的序列。


2.待排序列(25,57,48,37,12,92,86)




归并排序实现源码:

static Ret merge_sort_impl(void** storage, void** array, size_t low, size_t mid, size_t high, DataCompareFunc cmp)
{
    size_t i = low;
    size_t j = low;
    size_t k = mid;

    if((low + 1) < mid)
    {
        size_t x = low + ((mid - low) >> 1);
        merge_sort_impl(storage, array, low, x, mid, cmp);
    }
    
    if((mid + 1) < high)
    {
        size_t x = mid + ((high - mid) >> 1);
        merge_sort_impl(storage, array, mid, x, high, cmp);
    }

    
    while(j < mid && k < high)
    {
        if(cmp(array[j], array[k]) <= 0)
        {
            storage[i++] = array[j++];
        }
        else
        {
            storage[i++] = array[k++];
        }
    }

    while(j < mid)
    {
        storage[i++] = array[j++];
    }

    while(k < high)
    {
        storage[i++] = array[k++];
    }

    for(i = low; i < high; i++)
    {
        array[i] = storage[i];
    }

    return RET_OK;
}



  • 19
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值