From b2e8377e3d4b5fed8f635bde497c08b5624e82c8 Mon Sep 17 00:00:00 2001 From: LouisFonda Date: Sat, 8 Mar 2025 00:50:45 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B1=89=E8=AF=BA=E5=A1=94=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- recursion/tower-of-hanoi.js | 43 +++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 recursion/tower-of-hanoi.js diff --git a/recursion/tower-of-hanoi.js b/recursion/tower-of-hanoi.js new file mode 100644 index 0000000..8c738be --- /dev/null +++ b/recursion/tower-of-hanoi.js @@ -0,0 +1,43 @@ +/** +有三根柱子,分别命名为 A、B、C。A 上有若干个盘子,盘子的大小不等,且每个盘子都可以放在另一根柱子上。要求从柱子 A 上将所有盘子移动到柱子 C 上,且必须遵守以下规则: + +一次只能移动一个盘子。 +每次移动时,盘子只能从柱子顶部移动,且一个盘子不能放在比它小的盘子上。 +目标是使用柱子 B 作为辅助柱子,最少移动次数将盘子从柱子 A 移动到柱子 C。 + */ + +/** + * + * @param {number} n 汉诺塔问题的规模 + * 思路:假设我们只有两个盘子,只需要把小盘子移动到B柱上,再把大盘子移动到C柱子上,最后把小盘子从B柱移动到C柱子,我们把问题做一个抽象,假设有三个盘子,因为要想移动 + * 大盘子就必须把它上面的所有小盘子移动到B住上去,之后才能把这个大盘子移动到C柱,至于怎么移动我不管 + * + * 分析:假设现在有三个盘子,第一步我们发现底部的盘子无法直接移动,把问题抽象为移动n-1个盘子,在这里就是移动上面的两个盘子,之后会发现第二个盘子也移不动,所以再把问题抽象为 + * (n-1)-1,也就是移动第一个盘子,第一个盘子可以直接移动,这样就可以把第一个盘子移动到B上,第二个盘子移动到C,...... + */ +function towerOfHanoi(n) { + // 将n个盘子从A借助B移动到C + howToMove(n, 'A', 'C', 'B'); +} + +/** + * @param {*} n 要移动的所有盘子 + * @param {*} from 初始位置 + * @param {*} to 目标位置 + * @param {*} aux 辅助柱 + */ +function howToMove(n, from, to, aux) { + // 如果只有一个盘子那就直接移动到目标位置即可(这也是递归结束的条件) + if (n === 1) { + console.log(`${n} 从 ${from} 移动到 ${to}`); + return; + } + // 1.移动n-1个盘子,因为如果不把所有的小盘子移动到辅助位置,大盘子就不可能移动到目标位置 + howToMove(n - 1, from, aux, to); + // 2.将大盘子移动到目标位置 + console.log(`${n} 从 ${from} 移动到 ${to}`); + // 3.将剩下的所有盘子从辅助位置移动到目标位置 + howToMove(n - 1, aux, to, from); +} + +towerOfHanoi(3);