Skip to content

Commit efdf625

Browse files
committed
algorithm(recursion): add backtracking and hanoi tower
1 parent cd45d14 commit efdf625

15 files changed

+181
-20
lines changed

assets/alg-backtracking-1.jpg

108 KB
Loading

assets/alg-backtracking-2.jpg

311 KB
Loading

assets/alg-backtracking-3.jpg

87.6 KB
Loading

assets/alg-backtracking-4.jpg

80.2 KB
Loading

docs/README.Study.md

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,22 @@
1111
- [排序算法介绍](#排序算法介绍)
1212
- [基于比较的排序算法](#基于比较的排序算法)
1313
- [快速排序](#快速排序)
14-
- [合并排序的优化](#合并排序的优化)
15-
- [计数排序](#计数排序)
16-
- [基数排序](#基数排序)
17-
- [桶排序](#桶排序)
18-
- [外部排序](#外部排序)
14+
- [合并排序的优化](#合并排序的优化)
15+
- [计数排序](#计数排序)
16+
- [基数排序](#基数排序)
17+
- [桶排序](#桶排序)
18+
- [外部排序](#外部排序)
19+
- [递归](#递归)
20+
- [递归的基本概念](#递归的基本概念)
21+
- [汉诺塔](#汉诺塔)
22+
- [用递归绘制图形](#用递归绘制图形)
23+
- [递归和穷举问题](#递归和穷举问题)
24+
- [子集](#子集)
25+
- [全排列](#全排列)
26+
- [组合问题](#组合问题)
27+
- [递归空间优化](#递归空间优化)
28+
- [回溯算法](#回溯算法)
29+
1930

2031
## 时间复杂度和空间复杂度
2132

src/algorithm/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# 常见算法

src/algorithm/recursion/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# 递归
2+
3+
## 传送门
4+
5+
- [求一个数组的子集](./subsets.js)
6+
- [回溯算法](./backtracking.md)
7+
- 老鼠逃出迷宫
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* @desc 回溯算法 - 老鼠逃出迷宫
3+
* @param {Array<Array>} maze 二维数组的矩阵迷宫
4+
* 0表示没有走过的路 1表示墙体 2表示出口
5+
* @param {Array<Number>} pos 当前位置
6+
* @param {Array<Array>} path 路径
7+
* @param {Array<Number>} transverse 记录走过的地方
8+
* @return {Array<Array>} path 走出迷宫的路径
9+
*/
10+
export function rat_in_maze (
11+
maze, pos = [0, 0], path = [[...pos]], transverse = []
12+
) {
13+
const [x, y] = pos
14+
if (maze[x][y] === 2) { // 结束条件
15+
return path
16+
}
17+
// 记录走过的位置
18+
transverse[x * maze.length + y] = 1
19+
// 寻找可能的方向路径
20+
const choices = [
21+
[x + 1, y], [x - 1, y], // 向右 左
22+
[x, y + 1], [x, y - 1] // 向上 下
23+
].filter(([nextX, nextY]) => {
24+
return nextX >=0 && nextY >= 0 // 上 左 边界
25+
&& nextX < maze.length && nextY < maze[0].length // 右 下 边界
26+
&& maze[nextX][nextY] !== 1 // 非墙体
27+
&& !transverse[nextX * maze.length + nextY] // 非已经走过的格子
28+
})
29+
// 对每个选择 继续递归 寻找路径
30+
for (const [nextX, nextY] of choices) {
31+
const p = rat_in_maze(maze, [nextX, nextY], path.concat([[nextX, nextY]]), transverse)
32+
if (p) return p
33+
}
34+
}
35+
36+
// TODO remove Test
37+
const maze = [ // 构建迷宫
38+
[0, 1, 0, 0, 0, 0],
39+
[0, 1, 0, 1, 1, 0],
40+
[0, 0, 0, 1, 0, 1],
41+
[1, 1, 0, 0, 0, 1],
42+
[0, 0, 0, 1, 1, 1],
43+
[2, 1, 0, 0, 0, 0]
44+
]
45+
console.log(rat_in_maze(maze))
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# 回溯算法
2+
3+
## 目录
4+
5+
- [老鼠逃出迷宫](#老鼠逃出迷宫)
6+
7+
## 老鼠逃出迷宫
8+
9+
![alg-backtracking-1](../../../assets/alg-backtracking-1.jpg)
10+
![alg-backtracking-2](../../../assets/alg-backtracking-2.jpg)
11+
![alg-backtracking-3](../../../assets/alg-backtracking-3.jpg)
12+
![alg-backtracking-4](../../../assets/alg-backtracking-4.jpg)
13+
14+
- [详细实现及测试用例](./backtracking.js)

src/algorithm/recursion/subsets.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* @desc 求一个数组的子集
3+
*/
4+
export function * subsetsGen (array) {
5+
for (let i = 0; i < 1 << array.length; i++) {
6+
let ret = []
7+
for (let k = 0; k < array.length; k++) {
8+
const take = i & (1 << k)
9+
take && ret.push(array[k])
10+
}
11+
yield ret.join('')
12+
}
13+
}
14+
15+
export function subsets (array) {
16+
let outRet = []
17+
for (let i = 0; i < 1 << array.length; i++) {
18+
let ret = []
19+
for (let k = 0; k < array.length; k++) {
20+
const take = i & (1 << k)
21+
take && ret.push(array[k])
22+
}
23+
outRet.push(ret.join(''))
24+
}
25+
return outRet
26+
}
27+
28+
// TODO remove Test
29+
const array = ['a', 'b', 'c', 'd']
30+
console.log([...subsetsGen(array)])
31+
console.log(subsets(array))

0 commit comments

Comments
 (0)