美文网首页
归并排序

归并排序

作者: Pober_Wong | 来源:发表于2018-09-09 21:51 被阅读35次

本来是要探究多路归并的最优解的,却无意间碰到了归并排序,那就深入了解一下吧。

先来了解一下什么是 分治法

大体思路

  1. 将集合看作是 n 个长度为 1 的有序子表
  2. 两两归并,得到 n/2 个长度为 2 的子表
image

叶子结点即是数据的初态,根节点为排序之后的结果。由于分治法的实现应用常常以递归的形式出现,结合递归也是操作树结构最经典方式,由此可见递归没跑了。

递归一般由两个步骤组成:

  1. 递进过程
  2. 回归过程

由于我们的排序是自下而上进行归并排序的,可以得出对原数据的切分,应该是处于递进的过程,也就是整个递归栈被构建的过程。而核心排序应该是位于调用栈里每一个函数帧在弹栈时,对上一帧后续代码的执行中。这里应该再来一张图来描述递进的过程中将每一个数据切分到叶子节点上的示例。
温馨提示:大脑中应当正确地模拟栈的整个操作,有注意理解函数的执行过程

Code Time

function mergeSort(arr, first, last) { // 构建递归结构
  if(last - first < 1) { // 递进结束,已经到叶子节点,开始弹栈回归
    return
  }
  let middle = Math.floor((first + last) / 2)
  mergeSort(arr, first, middle) // 开始构建递归树
  mergeSort(arr, middle + 1, last)
  
  sortCurArr(arr, first, last, middle) // 当前节点的子树执行完毕弹栈后,开始排序当前 first~last 的子数组
}

/**
 * 对当前范围的元素开始排序
 * 由于是递归回归过程中调用的部分,因此可以得出 middle 左右两侧的数据都是有序的,
 * 因为插入排序对于相对有序的数据集来说效率是最高的,因此我们采用了改进后的插入排序
 */
function sortCurArr(arr, first, last, middle) {
  let tmp // 插入排序的辅助变量
  while(middle >= first && middle + 1<= last) { // 终止条件为
    if(arr[middle+1] <= arr[first]) {
      tmp = arr[middle + 1] // 临时取出要插入的元素
      for(let i = middle; i >= first; i--) { // 并将从要插入的位置开始到当前临界位置的元素一律后移,并插入
        arr[i+1] = arr[i]
      }
      arr[first] = tmp
      middle++
    } else {
      first++
    }
  }
}

改进后的插入排序
正常的插入排序是从数据集第二个元素开始向前方合适的位置插入,时间复杂度计算方式为阶乘,值为 O(n^2)。
这里不同的是,我们以 middle 之前的部分作为被插入的集合,之后的部分作为插入排序中无序的部分(实际上是有序的)。插入一次后,middle++ 可以理解,优化的部分就在于对 first 的自增,由于我们知道后半部分实际上是有序的,因此在我们得知要插入的元素大于前方有序集合中的 某元素 时,可以推断出要插入的该元素后方的元素也同样大于前方有序的 某元素, 因此 某元素 及其之前的部分就可以从对比的范围中剔除掉了。

小谈

起初让我不解的部分是:一般回归中操作数据,都会以返回数据值的方式来与弹栈之后的栈顶函数进行通信连接,这里并没有取递归的结果,更没有返回,只是以 return 结束递进。后来发现,递进的过程中,每次都使用的是原数组,而 sortCurArr 则是直接操作原数组,调用栈里每一帧作用域中的输入数组 —— 有序子表 都是以原数组加上 firstlast 进行标记生成的虚拟数组,因此函数调用结束后,只是将原数组的局部进行了重排。

参考:

相关文章

  • 排序算法

    约定 选择排序 冒泡排序 插入排序 希尔排序 归并排序1. 归并方法2. 自顶向下归并排序3. 自底向上归并排序 ...

  • 排序二:归并、快排

    文章结构 归并排序 快速排序 源码 1. 归并排序 1.1 什么是归并排序 归并排序的思想是:将待排序的区间平分成...

  • java归并排序

    归并排序什么是归并排序:图解归并排序归并排序有两种实现方式,一是基于递归,而是基于迭代1)基于递归的归并排序: 基...

  • 算法—排序篇2

    1、归并排序(Merging Sort) 归并排序(Merging Sort): 就是利用归并的思想实现排序⽅法....

  • 常见的排序算法(2)

    要点 快速排序 归并排序 1.快速排序 2.归并排序

  • 排序算法之归并排序

    归并排序(Merge Sort) 归并排序是利用归并的思想实现排序的方式,该算法采用的是经典的分治算法 归并排序过...

  • 算法 第二章第二部分笔记

    各种排序算法的性能特点 选择排序 插入排序 希尔排序 归并排序 本地归并排序 自底向上的归并排序 快速排序 三向切...

  • 归并排序(二路归并排序)

    归并排序的思路 归并排序是通过“归并”操作完成排序的,将两个或者多个有序子表归并成一个子表。归并排序是“分治法”的...

  • 算法排序之归并排序和快速排序

    归并排序和快速排序用的都是分治的思想,用递归的编程技巧来实现.咱们先来看归并排序. 归并排序 归并排序的核心思想就...

  • 基于左闭右开的乱序数组归并排序 2020-04-24(未经允许,

    归并排序代码模板 递归形式思路:二分nums数组后对nums的归并排序 = 对左侧数组归并排序+对右侧数组归并排序...

网友评论

      本文标题:归并排序

      本文链接:https://www.haomeiwen.com/subject/bbvdgftx.html