通过不同数据级级别,感性体验不通排序算法的效率。最下面代码,可直接拷贝后,运行后即可得到下方测试数据图。
结论:希尔排序和快速排序效率高,数据量对比才能体验到算法的重要性。
- 千条数据级别 区分不大
- 万条数据级别 快速排序,二分法排序,希尔排序效率突显
- 十万级别数据,希尔排序>快速排序 效率明显高很多可用;二分排序,冒泡和插入排序效率低,根本无法在百万级别里测试,等几十分钟不止。
- 百万级别数据测试,希尔排序>快速排序,快速排序效率还是很不错的。其他几种放法是不敢测的。
排序算法
- 冒泡算法
/**
*
* 冒泡算法
* @param {Array} arr
* @returns {Array} sorted result arr
*/
function popSort(arr) {
const retArr = [...arr];
for (let i = 0; i < retArr.length - 1; i++) {
for (let j = 0; j < retArr.length - i - 1; j++) {
count++;
if (retArr[j] > retArr[j + 1]) {
const swap = retArr[j + 1];
retArr[j + 1] = retArr[j];
retArr[j] = swap;
}
}
}
return retArr;
}
- 快速排序
/**
* 快速排序
*1将数列按照中间值分为两部分,左边的都比右边的小;
2调用递归,对左右两边继续排序
* @param {Array} arr
* @returns sorted arr
*/
function quickSort(arr) {
if (arr.length <= 1) {
return arr;
}
let middleIndex = Math.floor(arr.length / 2);
const middleItem = arr.splice(middleIndex, 1)[0];
let leftSide = [];
let rightSide = [];
for (let i = 0; i < arr.length; i++) {
if (arr[i] >= middleItem) {
rightSide.push(arr[i]);
} else {
leftSide.push(arr[i]);
}
}
return quickSort(leftSide).concat(middleItem, quickSort(rightSide));
}
- 插入排序
/**
*
* 插入排序
* @param {Array} arr
* @returns sorted arr
*/
function insertSort(arr) {
for (var i = 1; i < arr.length; i++) {
var item = arr[i];
var j = i - 1;
while (arr[j] > item) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = item;
}
return arr;
}
- 二分法排序
/**
*二分法排序
*
* @param {*} arr
* @returns sorted arr
*/
function binarySort(arr) {
for (var i = 1; i < arr.length; i++) {
var item = arr[i],
left = 0,
right = i - 1;
while (left <= right) {
var middle = parseInt((left + right) / 2);
if (item < arr[middle]) {
right = middle - 1;
} else {
left = middle + 1;
}
}
for (var j = i - 1; j >= left; j--) {
arr[j + 1] = arr[j];
}
arr[left] = item;
}
return arr;
}
- 希尔排序
/**
*希尔排序
*
* @param {*} arr
* @returns sorted arr
*/
function shellSort(arr) {
var len = arr.length,
item,
gap = 1;
while (gap < len / 5) {
//动态定义间隔序列
gap = gap * 5 + 1;
}
for (gap; gap > 0; gap = Math.floor(gap / 5)) {
for (var i = gap; i < len; i++) {
item = arr[i];
for (var j = i - gap; j >= 0 && arr[j] > item; j -= gap) {
arr[j + gap] = arr[j];
}
arr[j + gap] = item;
}
}
return arr;
}
开始测试
/**
* 初始化数据
*
* @param {Number} n 数据级别
* @returns new unsorted Array
*/
function initArr(n) {
let testArr = [];
for (let i = 0; i < n; i++) {
testArr.push(Math.floor(Math.random() * n));
}
return testArr;
}
//开始测试
Promise.all(
[popSort, quickSort, insertSort, binarySort, shellSort].map((fn, i) => {
// [quickSort, shellSort].map((fn, i) => {
return new Promise((resolve, reject) => {
const DATA_LENGTH = 10000; //修改大小来测试级别
const testArr = initArr(DATA_LENGTH);
console.log(`sorted data with length of ${DATA_LENGTH} by ${fn.name}`);
console.time("test");
const retArr = fn.call(null, testArr);
console.timeEnd("test");
resolve(retArr);
});
})
).then(result => log("done"));