❤ 写在前面
如果觉得对你有帮助的话,点个小❤❤ 吧,你的支持是对我最大的鼓励~
个人独立开发wx小程序,感谢支持!
📊 排序,不就是排座位吗?
想象一下,你是一位班主任,需要给全班同学按身高排座位——这就是排序!在前端开发中,我们每天都在进行各种“排座位”操作:商品按价格排序、文章按时间排序、用户按姓名排序...
但你知道吗?排座位的方式有很多种,有的快速但混乱,有的稳定但慢速。今天我们就来探索前端开发中那些有趣的排序方式!
🎯 排序算法分类图
flowchart TD
A[前端排序算法] --> B[基础排序算法]
A --> C[高级排序算法]
A --> D[JavaScript内置排序]
B --> B1[冒泡排序]
B --> B2[选择排序]
B --> B3[插入排序]
C --> C1[快速排序]
C --> C2[归并排序]
C --> C3[堆排序]
D --> D1[Array.sort<br/>默认算法]
D --> D2[自定义比较函数]
🔥 基础排序算法:三大经典招式
1. 冒泡排序 - “相邻交换法”
就像气泡从水底升到水面一样,每次比较相邻元素,把大的“冒”到后面。
// 冒泡排序实现
function bubbleSort(arr) {
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length - i - 1; j++) {
// 相邻元素比较,大的往后冒
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]; // ES6解构交换
}
}
}
return arr;
}
// 试试看!
console.log(bubbleSort([5, 3, 8, 1, 2])); // [1, 2, 3, 5, 8]
适用场景:教学演示、小数据量排序
2. 选择排序 - "选最小放前面"
每次找到最小的元素,放到已排序序列的末尾。
function selectionSort(arr) {
for (let i = 0; i < arr.length; i++) {
let minIndex = i;
// 找最小值的索引
for (let j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
// 把最小值放到前面
[arr[i], arr[minIndex]] = [arr[minIndex], arr[i]];
}
return arr;
}
3. 插入排序 - "扑克牌整理法"
就像整理扑克牌,每次把新牌插入到合适位置。
function insertionSort(arr) {
for (let i = 1; i < arr.length; i++) {
let current = arr[i];
let j = i - 1;
// 向前找到合适位置插入
while (j >= 0 && arr[j] > current) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = current;
}
return arr;
}
⚡ 高级排序算法:效率之选
快速排序 - "分而治之的王者"
选择一个基准,把小于基准的放左边,大于的放右边,然后递归处理。
function quickSort(arr) {
if (arr.length <= 1) return arr;
const pivot = arr[Math.floor(arr.length / 2)];
const left = [];
const right = [];
const equal = [];
for (let item of arr) {
if (item < pivot) left.push(item);
else if (item > pivot) right.push(item);
else equal.push(item);
}
return [...quickSort(left), ...equal, ...quickSort(right)];
}
时间复杂度:平均O(n log n),最坏O(n²)
🚀 JavaScript内置排序:Array.sort()
这才是我们日常最常用的!但你知道它默认按字符串Unicode排序吗?
// 惊喜还是惊吓?
[10, 2, 1].sort(); // [1, 10, 2] 😱
// 正确方式:提供比较函数
[10, 2, 1].sort((a, b) => a - b); // [1, 2, 10] ✅
📈 排序算法选择流程图
flowchart TD
Start[需要排序?] --> Condition1{数据量大小}
Condition1 -- "小数据量<br/>(< 100)" --> C1[基础算法即可<br/>冒泡/选择/插入]
Condition1 -- "大数据量" --> Condition2{是否需要稳定排序?}
Condition2 -- "是<br/>(相同值保持原顺序)" --> C2[归并排序]
Condition2 -- "否" --> Condition3{内存是否充足?}
Condition3 -- "充足" --> C3[快速排序<br/>通常最快]
Condition3 -- "紧张" --> C4[堆排序]
C1 --> D[使用JavaScript的<br/>Array.sort<br/>V8引擎自动优化]
C2 --> D
C3 --> D
C4 --> D
D --> End[完成排序!🎉]
💡 实战应用场景
场景1:电商商品排序
// 按价格排序
products.sort((a, b) => a.price - b.price);
// 多条件排序:先按销量,再按评分
products.sort((a, b) => {
if (a.sales !== b.sales) {
return b.sales - a.sales; // 销量降序
}
return b.rating - a.rating; // 评分降序
});
场景2:表格动态排序
// 可配置的表格排序
function sortTable(data, key, direction = 'asc') {
return [...data].sort((a, b) => {
const aVal = a[key];
const bVal = b[key];
if (direction === 'asc') {
return aVal < bVal ? -1 : aVal > bVal ? 1 : 0;
} else {
return aVal > bVal ? -1 : aVal < bVal ? 1 : 0;
}
});
}
场景3:中文排序
// 中文按拼音排序
const chineseNames = ['张三', '李四', '王五'];
chineseNames.sort((a, b) =>
a.localeCompare(b, 'zh-CN')
);
🎨 可视化排序过程(有趣实现)
// 动画演示冒泡排序
async function visualBubbleSort(arr, updateUI) {
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length - i - 1; j++) {
// 高亮比较的元素
updateUI(arr, { comparing: [j, j + 1] });
await delay(300); // 暂停一下,让用户看清
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
// 更新UI显示交换
updateUI(arr, { swapping: [j, j + 1] });
await delay(300);
}
}
}
updateUI(arr, { sorted: true });
}
📊 性能对比表
| 算法 | 平均时间复杂度 | 最佳情况 | 最坏情况 | 是否稳定 | 使用场景 |
|---|---|---|---|---|---|
| 冒泡排序 | O(n²) | O(n) | O(n²) | 是 | 教学、小数据 |
| 选择排序 | O(n²) | O(n²) | O(n²) | 否 | 小数据量 |
| 插入排序 | O(n²) | O(n) | O(n²) | 是 | 近乎有序的数据 |
| 快速排序 | O(n log n) | O(n log n) | O(n²) | 否 | 通用、大数据 |
| 归并排序 | O(n log n) | O(n log n) | O(n log n) | 是 | 需要稳定排序 |
| Array.sort | O(n log n) | O(n log n) | O(n log n) | 是 | 日常开发 |
🏆 总结与建议
- 日常开发:直接用
Array.sort(),现代JavaScript引擎已经高度优化 - 面试准备:理解各种排序原理,能手写1-2种即可
- 特殊需求:根据数据特点选择合适算法
- 性能关键:大数据量时,优先考虑快速排序或归并排序
记住,最好的排序算法不一定是理论上最快的,而是最适合你当前场景的!
彩蛋:试试这个"睡眠排序"(仅供娱乐,切勿生产使用!):
// 绝对不要在工作中使用这个!
function sleepSort(arr) {
arr.forEach(num => {
setTimeout(() => console.log(num), num * 10);
});
}
希望这篇博客让你对前端排序有了新的认识!在实际开发中,理解原理比死记硬背更重要。Happy coding! 🚀
点赞收藏这篇博客,下次面试被问到排序算法时,你就是最靓的仔!