项目被搁置了, 看文档看的瞌睡了, 来研究一下算法, 第一次(可能之前学习过,忘掉了)看到这种算法, 觉得挺有意思, 遂来深入分析一下:
第一步分为两段快速排序, 首先用数学公式退到一下遍历的次数(此处假设认为其他操作不耗时, 只有遍历操作耗时).
那么普通排序的遍历次数是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次的时候, 慢一点, 其他的时候, 速度优势是很明显的.