我有以下河内塔的工作程序,我们将从A - B塔移动磁盘,C是额外的塔。我定义了函数的初始状态如下:moveDisks(n, 'A', 'B', 'C');
每次我使用以下算法进行移动时都会打印:
public static void moveDisks(
int n,
char fromTower,
char toTower,
char auxTower)
{
if (n == 1) // Stopping condition
System.out.println(
"Move disk " + n + " from " + fromTower + " to " + toTower);
else
{
moveDisks(n - 1, fromTower, auxTower, toTower);
System.out.println(
"Move disk " + n + " from " + fromTower + " to " + toTower);
moveDisks(n - 1, auxTower, toTower, fromTower);
}
}
}
从我的程序中的递归调用可以看出,我有三个可能的调用:
A--B--C //fromTower, toTower,auxTower
A--C--B //fromTower, auxTower, toTower
C--B--A //auxTower, toTower, fromTower
但是,我正在为3
个磁盘获取以下打印输出:
The moves are:
Move disk 1 from A to B
Move disk 2 from A to C
Move disk 1 from B to C
Move disk 3 from A to B
Move disk 1 from C to A
Move disk 2 from C to B
Move disk 1 from A to B
我知道我的程序是正确的,但我并没有真正了解它是如何进行B--C
和C--A
调用的,因为我从未做过这样的函数/方法。如果你能证明这个递归的方式,我将不胜感激。方法使用我的A--B--C
,fromTower, toTower,auxTower
模型在三个磁盘方面工作。
答案 0 :(得分:3)
我终于弄清楚了这一点。我可以看到它在二进制树结构中令人惊讶,在递归中首先调用最左边的子节点(在这种情况下,子节点是一个print语句)。
我理解的错误是,我假设所有递归调用awk '{print gsub (srch,srch)}' srch="n"
为A--B--C
,尽管from-to-aux
变量一直在变化。所以当我开始时from-to-aux
和n=3
,我接到以下调用:A= from,B=to, C= aux
和moveDisks(2, 'A', 'C', 'B')
。现在,每个递归调用将独立启动自己的调用,但现在第一个调用{{ 1}}和第二个moveDisks(2, 'C', 'B', 'A')
。因此,对于第一个我得到A=from, C=to, and B=aux
和C=from, B=to and A=aux
来电,第二个得到moveDisks(1,'A','B','C')
和moveDisks(1,'B','C','A')
来电.Recursion继续到达停止点。
注意:这真是太神奇了!我正在学习递归,但最终也学习了二叉树!
答案 1 :(得分:0)
您正在考虑仅从初始调用的角度调用moveDisks
:
moveDisks(.., 'A', 'B', 'C')
将致电
moveDisks(.., 'A', 'C', 'B')
moveDisks(.., 'C', 'B', 'A')
但递归将继续进行这些调用,因此下一轮调用将是
moveDisks(.., 'A', 'B', 'C')
moveDisks(.., 'B', 'C', 'A') --> moving B to C
和
moveDisks(.., 'C', 'A', 'B')
moveDisks(.., 'A', 'B', 'C')
...