前端不懂算法(三)--归并排序

本篇文章参考借鉴了以下文章和极客时间的数据结构与算法一文,若涉及侵权,请联系我删除。

前言

  之前的博客里面我们一块学习了,冒泡排序,插入排序,选择排序,这三种排序算法,它们的时间复杂度都是O(n2),适用于小规模数据的排序,本篇文章,我们一块来学习下归并排序。适用于大规模数据。

没看过之前文章的小伙伴可以先了解一下

核心思想

  归并排序的核心思想是 分治思想 ,非常巧妙。我们可以借鉴这个思想,来解决非排序问题,比如:如何在O(n)的时间复杂度内查找一个无需数组的第 K 大元素?,这就用到了归并排序。

归并排序原理

  归并排序的实现原理还是比较简单的,如果要排序一个数组,我们先把数组从中间分成前后两个部分,然后对前后两部分分别排序,再将排好序的两部分合并在一起,这样整个数组就有序了。
在这里插入图片描述
  分治,顾名思义就是分而治之,将一个大问题分解成小的子问题来解决。小问题解决了,大问题也就解决了。

  从刚才的描述中可以看出,分治思想跟递归很像。是的,分治算法一般都是用递归实现的。分治是一种解决问题的处理思想,递归是一种编程技巧,这两者并不冲突。分治算法的思想我们放到后面的章节来梳理,现在不展开讨论,本篇文章重点还是排序算法。

如何实现归并排序

  如何用递归来实现归并排序?

  首先,递归代码的技巧是分析得出递推公式,找到终止条件,最后将递推公式翻译成递推代码。所以一起看看如何写出递推公式。

递推公式:
margin_sort(p...r) = merge(merge_sort(p...q), merge_sort(q+1...r))

终止条件:
p >= r不用再继续分了。

  该递推公式仔细观察就会发现:margin_sort(p...r)表示给下标从 p 到 r 之间的数组排序。现在将这个排序问题转化成两个子问题,margin_sort(p...q)margin_sort(q+1...r),其中 q 是 p 和 r 的中间位置,也就是(p + r)/2

  当下标从 p 到 q 和从 q + 1 到 r 这两个子数组都排序好之后,我们再将两个有序的子数组合并在一起,这样下标从 p 到 r 之间的数据也就好排序了。

  有了递推公式,下一步就是转换成代码了,各位请看:

//归并排序算法
function mergeSort(arr) {
   
   
  mergeSortFn(arr, 0, arr.length - 1)
}

//递归调用函数
function mergeSortFn(arr, p, r) {
   
   
  //递归终止条件
  if (p >= r) return;

  //取 p 到 r 之间的中位数 q
  let q = parseInt((p + r) / 2);

  //分治递归
  mergeSortFn(arr, p, q
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值