algorighm/recursion/tower-of-hanoi.js
2025-03-08 00:50:45 +08:00

44 lines
2.2 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
有三根柱子,分别命名为 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);