js排序方法有很多,本文就常用的几种进行了总结,分别是快速排序,冒泡排序,插入排序,归并排序,选择排序。
实例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>5种排序方式</title>
</head>
<body>
<button onclick="sort('quick')">快速排序</button>
<button onclick="sort('bubble')">冒泡排序</button>
<button onclick="sort('merge')">归并排序</button>
<button onclick="sort('insert')">插入排序</button>
<button onclick="sort('select')">选择排序</button>
</body>
<script>
let arrLength = 10000
let arr = [1, 9, 28, 5, 19, 8, 27, 119, 43, 0, 4, 30, 13]
for (let i = 0; i < arrLength; i++) {
arr.push(Math.random(0, 1) * 10000)
}
console.log(arr)
function sort(type) {
let nowArr = [...arr]
let newArr = []
let startTime = new Date().getTime()
switch (type) {
case 'quick':
newArr = quickSort(nowArr);
break;
case 'bubble':
newArr = bubbleSort(nowArr);
break;
case 'merge':
newArr = mergeSort(nowArr);
break;
case 'insert':
newArr = insertSort(nowArr);
break;
case 'select':
newArr = selectSort(nowArr);
break;
}
let endTime = new Date().getTime()
console.log(`${type}排序耗时${endTime - startTime}`)
// console.log(arr)
// console.log(newArr)
}
// 快速排序
function quickSort(arr) {
if (arr.length <= 1) {
return arr
}
let centerIndex = Math.floor(arr.length / 2)
let centerEle = arr.splice(centerIndex, 1)[0]
let leftArr = [];
let rightArr = [];
for (let i = 0; i < arr.length; i++) {
if (arr[i] < centerEle || arr[i] === centerEle) {
leftArr.push(arr[i])
} else {
rightArr.push(arr[i])
}
}
return quickSort(leftArr).concat([centerEle], quickSort(rightArr))
}
// 冒泡排序 从第一项开始与后面的每一项进行比较,如果大于后面的项就交换位置
function bubbleSort(arr) {
if (arr.length <= 1) {
return arr
}
for (let i = 0; i < arr.length; i++) {
// 把最大的数放到后面,较小的项逐渐向左移动
// 数组的最后一项和前面数组中最大的交换位置
// 第一次比较 arr.length-1 和数组最后一项
// 第二次比较 arr.length-2 和数组倒数第二项
// ...
for (let j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
let tem = arr[j + 1]
arr[j + 1] = arr[j]
arr[j] = tem
}
}
}
return arr
}
// 归并排序(分而治之)
// 1.不断将数组对半分,直到每个数组只有一个
// 2.将分出来的部分重新合并
// 3.合并的时候按顺序排列
function merge(left, right) {
// debugger
var result = [],
left_index = 0,
right_index = 0;
// 将两个数组合并
// 合并的时候按从小到大的顺序
while (left_index < left.length && right_index < right.length) {
if (left[left_index] < right[right_index]) {
result.push(left[left_index++]);
} else {
result.push(right[right_index++]);
}
}
// 和其他数组拼接
return result.concat(left.slice(left_index)).concat(right.slice(right_index));
}
function mergeSort(arr) {
// 只有一个数的时候退出递归
if (arr.length < 2) {
return arr;
}
var middle = Math.floor(arr.length / 2),
left = arr.slice(0, middle),
right = arr.slice(middle);
// 递归
// 不断拆分只到一个数组只有一个数
return merge(mergeSort(left), mergeSort(right));
}
// 选择排序 在数组中找到最小的项放到数组的第一位,再找到数组中第二小的项,放到第二位,以此类推
function selectSort(arr) {
var len = arr.length,
min;
for (i = 0; i < len; i++) {
// 将当前位置设为最小值
min = i;
// 检查数组其余部分是否更小
for (j = i + 1; j < len; j++) {
if (arr[j] < arr[min]) {
min = j;
}
}
// 如果当前位置不是最小值,将其换为最小值
if (i != min) {
swap(arr, i, min);
}
}
return arr;
}
function swap(arr, p1, p2) {
var temp = arr[p1];
arr[p1] = arr[p2];
arr[p2] = temp;
}
// 插入排序
// 1.把数组分为[已排序]和[未排序]两部分, 第一个数组为[已排序],其余为[未排序]
// 2.从[未排序]抽出第一个数,和[已排序]部分比较,插入到合适的位置
function insertSort(arr) {
if (arr.length <= 1) {
return arr
}
var len = arr.length, // 数组的长度
value, // 当前比较的值
i, // 未排序部分的当前位置
j; // 已排序部分的当前位置
for (i = 0; i < len; i++) {
// 储存当前位置的值
value = arr[i];
/*
* 当已排序部分的当前元素大于value,
* 就将当前元素向后移一位,再将前一位与value比较
*/
for (j = i - 1; j > -1 && arr[j] > value; j--) {
arr[j + 1] = arr[j];
}
arr[j + 1] = value;
}
return arr;
}
</script>
</html>
对30000个数据测试,v8引擎,结果如下
测试3次:
平均值为:
排序方式 | 第一次 | 第二次 | 第三次 | 平均值 |
quick | 59 | 21 | 26 | 34.33 |
bubble | 1690 | 1651 | 1622 | 1654.33 |
merge | 69 | 78 | 92 | 79.66 |
insert | 289 | 256 | 230 | 258.33 |
select | 1008 | 991 | 1052 | 1017 |
数据量较大时,排序性能:quick>mrege>insert>select>bubble