【每日算法】归并排序及其应用(逆序对&合并有序链表)

归并排序是建立在归并操作上的排序算法,是采用分治法(Divide and Conquer)的一个非常典型的应用,它常用来做外排序。

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

外排序

外排序(External sorting)是指能够处理极大量数据的排序算法。通常来说,外排序处理的数据不能一次装入内存,只能放在读写较慢的外存储器(通常是硬盘)上。外排序通常采用的是一种“排序-归并”的策略。在排序阶段,先读入能放在内存中的数据量,将其排序输出到一个临时文件,依此进行,将待排序数据组织为多个有序的临时文件。之后在归并阶段将这些临时文件组合为一个大的有序文件,也即排序结果。常见的有外归并排序。

(参考:百度百科)

分治模式

分解:将n个元素分成各含n/2个元素的子序列;
解决:用归并排序法对两个子序列递归地排序;
合并:合并两个已排序的子序列以得到排序结果。

当子序列长度为1时,递归结束,单个元素被视为是已排好序的。

基于以上思路,我们写出归并排序的代码:

void mergeSort(int arr[], int l, int r)
{
    if (NULL == arr || l >= r)
        return ;
    int m = l + (r-l)/2;
    mergeSort(arr, l, m);
    mergeSort(arr, m+1, r);
    merge(arr, l, m, r);
}

接下来的重点就是merge()函数了。

二路归并

merge()函数将两个有序的数组合并成一个有序的数组。

为理解这个过程,我们以摸扑克牌为例:

桌面上有两堆已排好序的牌(比如最上面的牌最小),牌面朝上。我们的任务是将两堆牌合并成一堆有序的牌。

下面开始取牌:

从两堆牌顶上的两张牌中选取较小的一张,将其取出,面朝下放到输出堆中。如果反复取牌直到其中一堆牌为空,接下来只要把剩下那堆牌(如果有的话)的所有牌都取出并放到输出堆中即可。

如果有n张牌那么我至多只需要比较n次,所以合并的时间为O(n)。

我们将上面的想法用代码来实现:

void merge(int arr[], int l, int m, int r)
{
    int index_l = l, index_r = m+
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值