快速排序JS版

228 阅读2分钟

陈姥姥的快排JS版

完整代码

快速排序

// 阈值
const Cutoff = 50;
// 核心
var QuickSort = function (arr, left, right) {
  if (Cutoff <= right - left) {
    var pivot = median3(arr, left, right);
    // console.log(type, arr.slice(left, right + 1), left, right);
    let Low = left,
      High = right - 1;
    for (;;) {
      while (arr[++Low] < pivot) {}
      while (arr[--High] > pivot) {}
      0;
      if (Low < High) arr.swap(Low, High);
      else break;
    }
    arr.swap(Low, right - 1);
    // console.log(`${left},${Low - 1}|${Low + 1},${right}`);
    QuickSort(arr, left, Low - 1, "left");
    QuickSort(arr, Low + 1, right, "right");
  } else {
    Insertion_Sort_Span(arr, left, right - left + 1);
  }
};
//对外暴露统一格式,接收(要排序数组,排序个数) //姥姥用的是C语言,我这里其实是可以用length的
var Quick_Sort = function (arr, n) {
  QuickSort(arr, 0, n - 1);
  return arr;
};

辅助函数

简单排序--插入排序

// Insertion_Sort_Span 当数量级足够小的时候,使用简单排序
var Insertion_Sort_Span = function (arr, left, length) {
  for (let p = left + 1; p < left + length; p++) {
    //根据偏移位,从第二张牌开始插入,第一张牌不用排
    let tmp = arr[p]; //摸下一张牌  ,摸牌要摸到  第[下标为left+length-1]张牌
    for (var i = p; i > 0 && arr[i - 1] > tmp; i--) {
      //这里不能用let哦,停下来想一想吧
      arr[i] = arr[i - 1]; //移出空位
    }
    arr[i] = tmp; //新牌落位
  }
  return arr;
};

swap,选择主元

// swap 将第i个与第j个进行交换
Object.defineProperty(Array.prototype, "swap", {
  value: function (i, j) {
   var _temp = this[i];
    this[i] = this[j];
    this[j] = _temp;
    _temp = null;
  },
  writable: true,
  configurable: true,
  enumerable: false,
});

// median3 选取三个数,按小中大排序,取中间的值作为主元
function median3(arr, left, right) {
  var center = parseInt((left + right) / 2);
  if (arr[left] > arr[center]) {
    arr.swap(left, center);
  }
  if (arr[left] > arr[right]) {
    arr.swap(left, right);
  }
  if (arr[center] > arr[right]) {
    arr.swap(center, right);
  }
  /* 此时A[Left] <= A[Center] <= A[Right] */
  arr.swap(center, right - 1); /* 将基准Pivot藏到右边*/
  /* 只需要考虑A[Left+1] … A[Right-2] */
  return arr[right - 1]; /* 返回基准Pivot */
}

测试用例


(function () {
  const n = 1000000;
  let needSortArr = [];
  for (var i = 0; i < n; i++) {
    needSortArr.push(Math.round(Math.random() * 100));
  }

  /*验证 */
  var copyArray = JSON.parse(JSON.stringify(needSortArr));
  var beginTime1 = +new Date();
  copyArray = copyArray.sort((a, b) => a - b);
  var endTime1 = +new Date();
  console.log(`JS原生Sort在${n}个数量级,用时共计${endTime1 - beginTime1}ms`);
  /*验证 */

  /*测试区 */
  var beginTime = +new Date();
  Quick_Sort(needSortArr, needSortArr.length);
  var endTime = +new Date();
  let span = endTime - beginTime;
  /*测试区 */

  const isRight = !copyArray.some((el, i) => el !== needSortArr[i]);
  if (isRight) {
    console.log(`测试成功!快速排序Cutoff为${Cutoff}时,用时共计${span} ms`);
  } else {
    console.log(copyArray);
    console.log(needSortArr);
  }
})();

keyword

浙江大学数据结构陈越快速排序