
一、冒泡排序
双层循环 内层循环两两比较换位,直到当前轮次的最大的数被交换至末尾
GIF图

代码
javascript
// 冒泡排序
const sort = (arr) => {
for (let i = 0; i < arr.length - 1; i++) {
let swap = false;
for (let j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
swap = true;
}
}
if (!swap) {
break;
}
}
return arr
};
// 测试
const arr = [5, 3, 8, 4, 2];
console.log(sort(arr)); // [2, 3, 4, 5, 8]
二、选择排序
将数组分为 "已排序区" 和 "未排序区",每轮从未排序区找到最小元素,放到已排序区末尾
GIF图
代码
javascript
// 选择排序(优化版)
const sort = (arr) => {
// 最后一个元素不需要再找最小值,因为前面都已经排序好了
for (let i = 0; i < arr.length - 1; i++) {
let tempIndex = i;
for (let j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[tempIndex]) {
tempIndex = j;
}
}
// 避免不必要的交换
if (tempIndex !== i) {
[arr[i], arr[tempIndex]] = [arr[tempIndex], arr[i]];
}
}
return arr;
};
// 测试
const arr = [5, 3, 8, 4, 2];
console.log(sort(arr)); // [2, 3, 4, 5, 8]
三、插入排序
将数组分为 "已排序区" 和 "未排序区",逐个取未排序区元素,插入到已排序区的正确位置
GIF图

代码
javascript
// 插入排序
const sort = (arr) => {
for (let i = 1; i < arr.length; i++) {
// 保存当前要插入的元素
const currentItem = arr[i];
let j = i - 1;
// 将比 currentItem 大的元素向后移动
while (j >= 0 && arr[j] > currentItem) {
arr[j + 1] = arr[j];
j--;
}
// 将 currentItem 插入到正确位置
arr[j + 1] = currentItem;
}
return arr;
};
// 测试
const arr = [5, 3, 8, 4, 2];
console.log(sort(arr)); // [2, 3, 4, 5, 8]
四、快速排序
分治思想 ------ 选一个 "基准值",将数组分为 "小于基准""等于基准""大于基准" 三部分,递归排序左右两部分
GIF图

代码
javascript
// 快速排序
const sort = (arr) => {
if (arr.length <= 1) {
return arr;
}
const sign = arr[Math.floor(arr.length / 2)];
const left = [];
const center = [];
const right = [];
for (let i = 0; i < arr.length; i++) {
if (arr[i] < sign) {
left.push(arr[i]);
} else if (arr[i] === sign) {
center.push(arr[i]);
} else {
right.push(arr[i]);
}
}
return [...sort(left), ...center, ...sort(right)];
};
// 测试
const arr = [5, 3, 8, 4, 2];
console.log(sort(arr)); // [2, 3, 4, 5, 8]
五、归并排序
分治思想 ------ 先把数组拆分成最小单元(单个元素),再两两合并成有序数组,最终合并为完整有序数组
GIF图

代码
javascript
// 归并排序
const sort = (arr) => {
if (arr.length <= 1) {
return [...arr];
}
const middle = Math.floor(arr.length / 2);
const left = sort(arr.slice(0, middle));
const right = sort(arr.slice(middle));
const merge = (_left, _right) => {
const arr = [];
let i = 0;
let j = 0;
while (i < _left.length && j < _right.length) {
if (_left[i] < _right[j]) {
arr.push(_left[i++]);
} else {
arr.push(_right[j++]);
}
}
return [...arr, ..._left.slice(i), ..._right.slice(j)];
};
return merge(left, right);
};
// 测试
const arr = [5, 3, 8, 4, 2];
console.log(sort(arr)); // [2, 3, 4, 5, 8]
六、手写Array.prototype.sort()
使用快速排序手写一个sort方法
GIF图

代码
javascript
// 手写Array.prototype.sort()
const sort = (arr, fn) => {
if (arr.length <= 1) {
return [...arr];
}
function defaultFn(a, b) {
const _a = String(a);
const _b = String(b);
if (_a < _b) return -1;
if (_a > _b) return 1;
return 0;
}
const compareFn = fn ? fn : defaultFn;
const left = [];
const center = [];
const right = [];
const sign = arr[Math.floor(arr.length / 2)];
for (let i = 0; i < arr.length; i++) {
if (compareFn(arr[i], sign) < 0) {
left.push(arr[i]);
} else if (compareFn(arr[i], sign) > 0) {
right.push(arr[i]);
} else {
center.push(arr[i]);
}
}
return [...sort(left, compareFn), ...center, ...sort(right, compareFn)];
};
// 测试
const arr = [5, 3, 8, 4, 2];
console.log(sort(arr)); // [2, 3, 4, 5, 8]
