JavaScript排序算法(二)——合并排序

基本思想

一个分治的战略,先举行分别,然后再举行兼并
空间复杂度:nLogn

自顶向下的合并排序

采纳递归的体式格局,要领比较简约

function mergeSort(arr){
  // 设置停止的前提,
  if (arr.length < 2) {
    return arr;
  }
  //设立中心值
  var middle = parseInt(arr.length / 2);
  //第1个和middle个之间为左子列
  var left = arr.slice(0, middle);
  //第middle+1到末了为右子列
  var right = arr.slice(middle);
  if(left=="undefined"&&right=="undefined"){
     return false;
  }
  return merge(mergeSort(left), mergeSort(right));
}

function merge(left, right){
  var result = [];

  while (left.length && right.length) {
    if(left[0] <= right[0]){
      //把left的左子树推出一个,然后push进result数组里
       result.push(left.shift());
    }else{
      //把right的右子树推出一个,然后push进result数组里
     result.push(right.shift());
    }
  }
  //经由上面一次轮回,只能左子列或右子列一个不为空,或许都为空
  while (left.length){
    result.push(left.shift());
  } 
  while (right.length){
    result.push(right.shift());
  }
  return result;
}
// 测试数据
var nums=[6,10,1,9,4,8,2,7,3,5];
mergeSort(nums);

自底向上的合并排序

递归的深度太深,运用一种非递归的体式格局。首先将数据集分解为一组只要一个元素的数组,然后经由过程竖立一组摆布子数组逐步将它们兼并起来,
每次兼并都保留一部分排好序的数据,末了这个数组排序完整。

function mergeSort(arr){
  if(arr.length<2){
    return;
  }
  //设置子序列的大小
  var step=1; 
  var left,right;
  while(step<arr.length){
    left=0;
    right=step;
    while(right+step<=arr.length){
      mergeArrays(arr,left,left+step,right,right+step);
      left=right+step;
      right=left+step;
    }
    if(right<arr.length){
      mergeArrays(arr,left,left+step,right,arr.length);
    }
    step*=2;
  }
}
//对摆布序列举行排序
function mergeArrays(arr,startLeft,stopLeft,startRight,stopRight){
  // 竖立一个左、右数组
  var rightArr=new Array(stopRight-startRight+1);
  var leftArr=new Array(stopLeft-startLeft+1);
  // 给右数组赋值
  k=startRight;
  for(var i=0;i<(rightArr.length-1);++i){
    rightArr[i]=arr[k];
    ++k;
  }
   // 给左数组赋值
  k=startLeft;
  for(var i=0;i<(leftArr.length-1);++i){
    leftArr[i]=arr[k];
    ++k;
  }
  //设置尖兵值,当左子列或右子列读取到末了一名时,即Infinity,能够让另一个剩下的列中的值直接插入到数组中
  rightArr[rightArr.length-1]=Infinity;
  leftArr[leftArr.length-1]=Infinity;
  var m=0;
  var n=0;
  // 比较左子列和右子列第一个值的大小,小的先填入数组,接着再举行比较
  for(var k=startLeft;k<stopRight;++k){
    if(leftArr[m]<=rightArr[n]){
      arr[k]=leftArr[m];
      m++; 
    }
    else{
      arr[k]=rightArr[n];
      n++;
    }
  }
}
// 测试数据
var nums=[6,10,1,9,4,8,2,7,3,5];
mergeSort(nums);

参考资料

  1. Sorting Algorithms in Javascript

  2. 《Data Structures& Algorithms with JavaScript》Michael McMilan著

    原文作者:hopeCoder
    原文地址: https://segmentfault.com/a/1190000006261074
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞