JavaScript实现的九种排序算法详解
本文汇总了JavaScript中九种常见排序算法的实现代码,包括冒泡、选择、插入、二分插入、快速、原地快速及希尔排序。文章提供了完整的源码参考,并通过控制台彩色打印效果演示排序过程,同时提供了GitHub源码链接以便深入学习。
引言
前言
排序是数据结构的核心内容之一,其重点在于算法思想而非特定编程语言。过去曾使用C语言研究过排序实现,近期利用空闲时间,使用JavaScript重新梳理并熟悉这些排序知识点。
接下来直接介绍具体内容。
基础排序算法实现
一、代码汇总(一)
1、冒泡排序
2、改进版冒泡排序
3、选择排序
4、直接插入排序
5、二分插入排序
/*
* @Author: laifeipeng
* @Date: 2019-02-20 10:00:36
* @Last Modified by: laifeipeng
* @Last Modified time: 2019-02-21 11:57:58
*/
/********* 1、冒泡排序 **********/
// 很常见很容易理解的排序算法, 排序思路:遍历数组,每次遍历就将最大(或最小)值推至最前。越往后遍历查询次数越少
const bubbleSort = arr => {
const list = arr.slice(); //保证函数为纯函数
const len = list.length;
for (let i = 0; i < len; i++) {
for (let j = len - 1; j > i; j--) {
if (list[j] < list[j - 1]) {
[list[j - 1], list[j]] = [list[j], list[j - 1]];
}
}
}
return list;
}
/********* 2、改进版冒泡排序 **********/
// 对上述冒泡排序的一种优化, 优化思路:当一次遍历前后数组不产生变化时,说明该数组已经有序,结束排序。
const bubbleSort2 = arr => {
const list = arr.slice(); //保证函数为纯函数
const len = list.length;
for (let i = 0; i < len; i++) {
let exchange = false;
for (let j = len - 1; j > i; j--) {
if (list[j] < list[j - 1]) {
[list[j - 1], list[j]] = [list[j], list[j - 1]];
exchange = true;
}
}
if (!exchange) return list
}
return list;
}
/********* 3、选择排序 **********/
// 在无序区中选出最小的元素,然后将它和无序区的第一个元素交换位置。
const selectionSort = arr => {
const list = arr.slice(); //保证函数为纯函数
const len = list.length;
for (let i = 0; i < len; i++) {
let k = i
for (let j = len - 1; j > i; j--) {
if (list[j] < list[k]) k = j;
}
if (k !== i) {
[list[k], list[i]] = [list[i], list[k]];
}
}
return list;
}
/********* 4、直接插入排序 **********/
// 每次选择无序区第一个元素插入到有序区,并排序
const insertSort = arr => {
const list = arr.slice(); //保证函数为纯函数
const len = list.length;
for (let i = 1; i < len; i++) {
const tmp = list[i];
let j = i - 1;
while (j >= 0 && tmp < list[j]) {
list[j + 1] = list[j];
j--;
}
list[j + 1] = tmp;
}
return list;
}
/********* 5、二分插入排序 **********/
// 插入排序的一种优化实现, 通过二分法减少遍历时间(以前是从某边开始依次比较,现在从中间开始比较,减少比较次数)
// 注意,数组很大才能提现二分插入的优势
const insertSort2 = arr => {
const list = arr.slice(); //保证函数为纯函数
const len = list.length;
for (let i = 1; i < len; i++) {
const tmp = list[i];
let low = 0;
let high = i - 1;
let j = i - 1;
while (low <= high) {
const mid = ~~((low + high) / 2);
if (tmp < list[mid]) {
high = mid - 1;
} else {
low = mid + 1;
}
}
while (j > high) {
list[j + 1] = list[j];
j--;
}
list[j + 1] = tmp;
}
return list;
}
高级排序算法实现
2、代码汇总(二)
6、快速排序
7、原地算法快速排序
8、希尔排序
堆排序、归并排序(js实现无优势,不作实现)
/********* 6、快速排序 **********/
const quickSort1 = arr => {
const list = arr.slice(); //为了保证这个函数是纯函数,拷贝一次数组
if (list.length <= 1) return list;
const pivot = list.splice(0, 1)[0]; //选第一个作为基数,并把基数从数组里面删除
const left = [];
const right = [];
for (let i = 0, len = list.length; i < len; i++) { //从0开始
if (list[i] < pivot) {
left.push(list[i]);
} else {
right.push(list[i]);
}
}
return [...quickSort(left), pivot, ...quickSort(right)];
}
// 上面const pivot = list.splice(0, 1)[0]; 如果想直接改为list[0],那么后面循环的时候要从i=1开始
const quickSort2 = arr => {
const list = arr.slice(); //为了保证这个函数是纯函数,拷贝一次数组
if (list.length <= 1) return list;
const pivot = list[0]; //选第一个作为基数
const left = [];
const right = [];
for (let i = 1, len = list.length; i < len; i++) { //从1开始
if (list[i] < pivot) {
left.push(list[i]);
} else {
right.push(list[i]);
}
}
return [...quickSort(left), pivot, ...quickSort(right)];
}
/********* 7、原地算法快速排序 **********/
const quickSort = arr => {
const list = arr.slice() // 为了保证这个函数是纯函数拷贝一次数组
const sort = (arr, left = 0, right = arr.length - 1) => {
if (left >= right) {//如果左边的索引大于等于右边的索引说明整理完毕
return;
}
let i = left;
let j = right;
const baseVal = arr[j]; // 取无序数组最后一个数为基准值
while (i < j) { //把所有比基准值小的数放在左边大的数放在右边
while (i < j && arr[i] <= baseVal) { //找到一个比基准值大的数交换
i++;
}
arr[j] = arr[i]; // 将较大的值放在右边如果没有比基准值大的数就是将自己赋值给自己(i 等于 j)
while (j > i && arr[j] >= baseVal) { //找到一个比基准值小的数交换
j--;
}
arr[i] = arr[j]; // 将较小的值放在左边如果没有找到比基准值小的数就是将自己赋值给自己(i 等于 j)
}
arr[j] = baseVal; // 将基准值放至中央位置完成一次循环(这时候 j 等于 i )
sort(arr, left, j - 1); // 将左边的无序数组重复上面的操作
sort(arr, j + 1, right); // 将右边的无序数组重复上面的操作
}
sort(list);
return list;
}
/********* 8、希尔排序 **********/
// 排序思路:先将整个待排序记录序列分割成若干个子序列,在序列内分别进行直接插入排序,待整个序列基本有序时,再对全体记录进行一次直接插入排序。
const shellSort = arr => {
const list = arr.slice(); //保证函数为纯函数
const len = list.length;
let gap = ~~(len / 2);
while (gap > 0) {
for (let i = gap; i < len; i++) {
const tmp = list[i];
let j = i - gap;
while (j >= 0 && tmp < list[j]) {
list[j + gap] = list[j];
j = j - gap;
}
list[j + gap] = tmp;
}
gap = ~~(gap / 2);
}
return list;
}

可视化效果与源码资源
3、效果图


4、解答
1、如何在控制台打印出上面图片中的彩色效果,eg:
const logStep = (i, leftArr, rightArr) =>
console.log(`%c 第${i}趟排序:%c ${arrStr(leftArr)} %c${arrStr(rightArr)} `, 'color:green', 'color:red', 'color:blue');
2、交换数组2元素:
// 交换下标为i,k的数组元素
[list[k], list[i]] = [list[i], list[k]];
3、所有源码github地址:
https://github.com/laifeipeng/utils/blob/master/sort/sort.js
4、彩色打印效果的github地址:
https://github.com/laifeipeng/utils/blob/master/sort/test.js
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对本站的支持。
JS动态构建复杂嵌套JSON对象的方法
2026-11-05 15:41:52
JS负数取余为什么是负数?详解余数与模运算区别
2026-11-05 13:34:41
JS 解压出现乱码或报错怎么解决?
2026-11-05 12:32:38
JS 中 startsWith、indexOf 与正则判断字符串前缀的对比
2026-11-04 22:19:43
JS解析Excel后怎么将数据转换为JSON格式
2026-11-04 20:58:28
