快速排序算法的深入分析

项目被搁置了, 看文档看的瞌睡了, 来研究一下算法, 第一次(可能之前学习过,忘掉了)看到这种算法, 觉得挺有意思, 遂来深入分析一下:

第一步分为两段快速排序, 首先用数学公式退到一下遍历的次数(此处假设认为其他操作不耗时, 只有遍历操作耗时).

那么普通排序的遍历次数是n * n-1, 分成两段的遍历次数是n + m * (m - 1) + (n - m - 1) * (n - m - 2) [1 < m < n],

解释一下后面这个公式, 前面的n是进行分组, 后面的是分两段进行普通排序, m代表第一段的长度.

(n * n-1) - (n + m * (m - 1) + (n - m - 1) * (n - m - 2) [1 < m < n]) = m * m - 2 *(n - 1) * (m + 2)

看上去这个公式恒小于零, 推导证明就不做了, 绕啊绕的苦涩难懂,  而且这里忽略了其他操作的耗时, 所以还是直接用代码说话吧:

import now from 'performance-now';

// Generate Array to Sort
const originArray = [];
const max = 10;
for (let k = 0; k < max; k++) {
  originArray[k] = Math.floor(Math.random() * max) + 1;
}
console.log("Origin       Array", JSON.stringify(originArray));
console.log();

const len = originArray.length;
let normalSort = [], quickSort = [], normalTimes = 0, quickTimes = 0;

var t0 = now();
//Normal Sort Method
normalSort = Array.from(originArray);
for (let i = 0; i < len; i++) {
  for (let j = i + 1; j < len; j++) {
    normalTimes++;
    if (normalSort[i] < normalSort[j]) {
      let temp = normalSort[i];
      normalSort[i] = normalSort[j];
      normalSort[j] = temp;
    }
  }
}

var t1 = now();

//Quick Sort Method
const half = Math.floor(len / 2);
let rightPart = [];
for (let i = 0; i < len; i++) {
  if (originArray[i] > originArray[half]) {
    quickSort.push(originArray[i]);
  } else {
    rightPart.push(originArray[i]);
  }
}
const splitLen = quickSort.length;
quickSort = quickSort.concat(rightPart);
for (let i = 0; i < splitLen; i++) {
  for (let j = i + 1; j < splitLen; j++) {
    quickTimes++;
    if (quickSort[i] < quickSort[j]) {
      let temp = quickSort[i];
      quickSort[i] = quickSort[j];
      quickSort[j] = temp;
    }
  }
}
for (let i = splitLen; i < len; i++) {
  for (let j = i + 1; j < len; j++) {
    quickTimes++;
    if (quickSort[i] < quickSort[j]) {
      let temp = quickSort[i];
      quickSort[i] = quickSort[j];
      quickSort[j] = temp;
    }
  }
}
var t2 = now();

console.log("Normal Sort Result", JSON.stringify(normalSort));
console.log("Quick Sort  Result", JSON.stringify(quickSort));
console.log();

console.log("NormalSort took " + (t1 - t0) + " milliseconds. loop times" + normalTimes);
console.log("QuickSort  took " + (t2 - t1) + " milliseconds. loop times" + quickTimes);

下面分别是数组长度对应10、100、1000...的执行时间:

 

可以看出, 除了1000次的时候, 慢一点, 其他的时候, 速度优势是很明显的.

猜你喜欢

转载自www.cnblogs.com/jerryqi/p/11468428.html