归并排序

来源:互联网 发布:旋极伏羲大数据 编辑:程序博客网 时间:2024/05/16 09:50

一、定义
所谓归并排序是指将两个或两个以上有序的数列(或有序表),合并成一个仍然有序的数列(或有序表)。这样的排序方法经常用于多个有序的数据文件归并成一个有序的数据文件。归并排序的算法比较简单。
二、基本思想

  • 采用分治法的思想
  • 假设已经有两个有序数列,分别存放在两个数组s,r中;并设i,j分别为指向数组的第一个单元的下标;s有n个元素,r有m个元素
  • 再另设一个数组a,k指向该数组的第一个单元下标

三、图解

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

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

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

这里写图片描述
四、代码实现

  • 递归算法
function merge(left, right) {  var tmp = [];  while (left.length && right.length) {    if (left[0] < right[0])      tmp.push(left.shift());    else      tmp.push(right.shift());  }  return tmp.concat(left, right);}function mergeSort(a) {  if (a.length === 1)     return a;  var mid =Math.floor(a.length / 2),  left = a.slice(0, mid),   right = a.slice(mid);  return merge(mergeSort(left), mergeSort(right));}
  • 非递归算法
function merge(left, right) {  var result = [];  while (left.length && right.length) {    if (left[0] < right[0])      result.push(left.shift());    else      result.push(right.shift());  }  return result.concat(left, right);}function mergeSort(a) {  if (a.length === 1)    return a;  var work = [];  for (var i = 0, len = a.length; i < len; i++)    work.push([a[i]]);  work.push([]); // 如果数组长度为奇数  for (var lim = len; lim > 1; lim = Math.floor((lim + 1) / 2)) {    for (var j = 0, k = 0; k < lim; j++, k += 2)       work[j] = merge(work[k], work[k + 1]);    work[j] = []; // 如果数组长度为奇数  }  return work[0];}