导航
var a = 2, b = 4;
// 使用“和”形式
function swap(a, b) {
a = a + b; // 此时 a 等于两数之和
b = a - b; // 两数之和 减 b 为 a,此时 b 为 a
a = a - b; // 两数之和 减 b,相当于减 a,此时 a 为 b
return [a, b];
}
// 利用解构赋值
function swap(a, b) {
[a, b] = [b, a];
return [a, b];
}
排序算法都可以理解成:
外层:处理第几个元素(第几轮)
内层:在这一轮中怎么比较(或查找)
相邻比较,大的往后挤。每一轮,把一个最大值“浮到最后”
var arr = [5, 3, 4, 1];
function bubbleSort(arr) {
var len = arr.length, temp;
// 外层:控制轮数
for (var i = 0; i < len - 1; i++) {
// 内层:相邻比较
for (var j = 0; j < len - i - 1; j++) {
// 如果前面比后面大,就交换
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
第1轮(i = 0)
| j | 操作 | 数组 |
|---|---|---|
| 0 | 5 > 3 swap | [3, 5, 4, 1] |
| 1 | 5 > 4 swap | [3, 4, 5, 1] |
| 2 | 5 > 1 swap | [3, 4, 1, 5] |
第2轮(i = 1)
| j | 操作 | 数组 |
|---|---|---|
| 0 | 3 < 4 | [3, 4, 1, 5] |
| 1 | 4 > 1 swap | [3, 1, 4, 5] |
第3轮(i = 2)
| j | 操作 | 数组 |
|---|---|---|
| 0 | 3 > 1 swap | [1, 3, 4, 5] |
选 pivot,一刀切左右,再递归
var arr = [5, 3, 8, 4, 2];
function quickSort(arr) {
if (arr.length <= 1) return arr;
var leftArr = [], rightArr = [], q = arr[0];
for (var i = 1; i < arr.length; i++) {
if (arr[i] > q) {
rightArr.push(arr[i]);
} else {
leftArr.push(arr[i]);
}
}
return [].concat(quickSort(leftArr), [q], quickSort(rightArr));
}
第1刀 pivot=5
left = [3, 4, 2]
right = [8]
左边继续
[3, 4, 2] → pivot=3
left=[2], right=[4]
合并
[2, 3, 4, 5, 8]
插入排序 = “整理扑克牌”, 不是交换,是“腾位置 + 插进去”
拿一张牌:
- 比左边大 → 放后面
- 比左边小 → 一直往左插
function insertionSort(arr) {
for (let i = 1; i < arr.length; i++) { // 为什么从 1 开始? 因为 0 默认已经“有序”
let item = arr[i]; // 把当前要插入的牌“先拿出来”
let j = i - 1; // j = 左边有序区的最后一个位置
// 往左找插入位置
while (j >= 0 && arr[j] > item) { // 如果左边的数比 key 大,就往右挪
arr[j + 1] = arr[j]; // 把大的往右移动一格, 这不是“交换”,而是:"搬家"
j--; // 继续往左找
}
arr[j + 1] = item; // 找到位置后,把要插入的牌放进去
}
return arr;
}
每轮都在“找最小值”
var arr = [5, 2, 8, 1];
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;
}
}
// 找到后交换
let temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
return arr;
}
第一轮(找最小值)
当前: [5, 2, 8, 1]
假设最小值是 5: min = 5
看 2: 2 < 5, 更新: min = 2
看 8: 8 > 2, 不变
看 1: 1 < 2, 更新: min = 1
第一轮结束:交换
把: 1 和 5 交换得到 [1, 2, 8, 5]
第二轮
现在: [1 | 2, 8, 5] , 前面的 1 已经锁定。
从剩余部分找最小, 最小是 2。不用换: [1, 2, 8, 5]
第三轮
现在: [1, 2 | 8, 5]
找最小: 5 < 8 , 交换: [1, 2, 5, 8]
类比:你在一个迷宫里找出口
| 算法 | 像什么? | 行为方式 |
|---|---|---|
| DFS(深度优先) | 一条路走到黑的人 | 第一条路一直往深处走,撞墙后再回到上一个分岔口换路 |
| BFS(广度优先) | 扫街式搜索的人 | 所有方向都先走一步 → 再走第二步 → 再走第三步……越来越远 |
对于算法来说 无非就是时间换空间 空间换时间