关于汉诺塔的递归过程和完成所需的最少步数的问题
Question regarding the recursive process of Tower of Hanoi and the minimum amount of moves require for completion
目前,我已经学习了 3 种不同的方法来计算解决汉诺塔的最小步数。
第一种方法是:2 的“圆盘”次方减 1。总而言之,非常简单易懂。
const towerHanoi = (discs) => 2**discs - 1;
console.log(towerHanoi(0)); // 0
console.log(towerHanoi(2)); // 3
console.log(towerHanoi(3)); // 7
console.log(towerHanoi(4)); // 15
console.log(towerHanoi(5)); // 31
console.log(towerHanoi(6)); // 63
第二种方法是使用“for 循环”。在每次迭代中,将“计数”添加到 2 的“i”次方的结果再次,非常直接和易于理解。
function towerHanoi(discs,count=0) {
for (let i = 0; i < discs; i++) count += 2**i;
return count;
}
然而,在递归的第三种方法中,我无法完全理解递归过程的概念。
const towerHanoi = (discs) => discs === 0 ? 0 : 2 * towerHanoi(discs-1) + 1;
让我们以5个圆盘为例来说明至少需要31步才能完成游戏的递归过程。我将尽力分解递归过程,如下所示:
2 * (5-1) + 1 === 9
2 * (4-1) + 1 === 7
2 * (3-1) + 1 === 5
2 * (2-1) + 1 === 3
2 * (1-1) + 1 === 1
9 + 7 + 5 + 3 + 1 --> 25 =/= 31
如您所见,我得到的是 25 而不是 31。我错过了什么。有人可以帮助我理解代码的递归过程吗?感谢阅读并提前万分感谢:)
这个递归公式背后的推理:
const towerHanoi = (discs) => discs === 0 ? 0 : 2 * towerHanoi(discs-1) + 1;
...如下:
假设我们知道如何将 discs-1
个圆盘从一堆移到另一堆。然后我们可以按如下方式使用该知识:
将除底部以外的所有棋子移动到中间位置(使用该知识)。然后将最大的圆盘移到最后一个位置。最后将中间的堆栈移到那个最大的圆盘上,再次应用该知识。
所以确实,我们需要将一叠 discs - 1
棋子移动两次,然后再移动一次。这给了我们公式的递归部分。
至于你对5盘的分析。您没有正确应用递归。 (5-1) 不能像这样计算——它仍然需要扩展到更深的递归级别。这是应该如何完成的:
2 * (
2 * (
2 * (
2 * (
2 * (
0 = 0 (base case)
) + 1 = 1
) + 1 = 3
) + 1 = 7
) + 1 = 15
) + 1 = 31
目前,我已经学习了 3 种不同的方法来计算解决汉诺塔的最小步数。
第一种方法是:2 的“圆盘”次方减 1。总而言之,非常简单易懂。
const towerHanoi = (discs) => 2**discs - 1;
console.log(towerHanoi(0)); // 0
console.log(towerHanoi(2)); // 3
console.log(towerHanoi(3)); // 7
console.log(towerHanoi(4)); // 15
console.log(towerHanoi(5)); // 31
console.log(towerHanoi(6)); // 63
第二种方法是使用“for 循环”。在每次迭代中,将“计数”添加到 2 的“i”次方的结果再次,非常直接和易于理解。
function towerHanoi(discs,count=0) {
for (let i = 0; i < discs; i++) count += 2**i;
return count;
}
然而,在递归的第三种方法中,我无法完全理解递归过程的概念。
const towerHanoi = (discs) => discs === 0 ? 0 : 2 * towerHanoi(discs-1) + 1;
让我们以5个圆盘为例来说明至少需要31步才能完成游戏的递归过程。我将尽力分解递归过程,如下所示:
2 * (5-1) + 1 === 9
2 * (4-1) + 1 === 7
2 * (3-1) + 1 === 5
2 * (2-1) + 1 === 3
2 * (1-1) + 1 === 1
9 + 7 + 5 + 3 + 1 --> 25 =/= 31
如您所见,我得到的是 25 而不是 31。我错过了什么。有人可以帮助我理解代码的递归过程吗?感谢阅读并提前万分感谢:)
这个递归公式背后的推理:
const towerHanoi = (discs) => discs === 0 ? 0 : 2 * towerHanoi(discs-1) + 1;
...如下:
假设我们知道如何将 discs-1
个圆盘从一堆移到另一堆。然后我们可以按如下方式使用该知识:
将除底部以外的所有棋子移动到中间位置(使用该知识)。然后将最大的圆盘移到最后一个位置。最后将中间的堆栈移到那个最大的圆盘上,再次应用该知识。
所以确实,我们需要将一叠 discs - 1
棋子移动两次,然后再移动一次。这给了我们公式的递归部分。
至于你对5盘的分析。您没有正确应用递归。 (5-1) 不能像这样计算——它仍然需要扩展到更深的递归级别。这是应该如何完成的:
2 * (
2 * (
2 * (
2 * (
2 * (
0 = 0 (base case)
) + 1 = 1
) + 1 = 3
) + 1 = 7
) + 1 = 15
) + 1 = 31