Java 试着用我自己的程序理解Hanoi算法

Java 试着用我自己的程序理解Hanoi算法,java,algorithm,recursion,tree,Java,Algorithm,Recursion,Tree,我有以下河内塔的工作程序,我们将从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

我有以下河内塔的工作程序,我们将从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
从塔到塔,在三个磁盘上演示这个递归方法是如何工作的,我将不胜感激,auxTower
模型。

您仅从初始调用的角度考虑对
移动磁盘的可能调用:

moveDisks(.., 'A', 'B', 'C')
将呼叫

moveDisks(.., 'A', 'C', 'B')
moveDisks(.., 'C', 'B', 'A')
但是,这些调用将继续递归,因此下一轮调用将是

moveDisks(.., 'A', 'B', 'C')
moveDisks(.., 'B', 'C', 'A')  --> moving B to C


我终于自己解决了这个问题。我可以看到它惊人地遵循二叉树结构,在递归中首先调用最左边的子级(在本例中,子级是print语句)

我理解中的错误是,对于所有递归调用,我假设
A--B--C
from to aux
,尽管
from to aux
变量一直在变化。因此,当我从
n=3
A=from,B=to,C=aux
开始时,我得到以下调用:
(2,'A','C','B')
moveDisks(2,'C','B','A')
。现在,这些递归调用中的每一个都将独立地启动它们自己的调用,但是对于第一个,现在
A=from,C=to,B=aux
和第二个
C=from,B=to和A=aux
。因此对于第一个,我得到
moveDisks(1,'A','B','C')
moveDisks(1,'B','C','A')
调用,我得到的第二个
moveDisks(1,'C','A','B')
moveDisks(1,'A','B','C')
调用。递归继续,直到到达停止点



注意:这太神奇了!我在学习递归,但最终也学习了二叉树!

用调试器运行它,看看到底发生了什么。调试程序告诉我它已经在运行。我如何调试已经在运行的程序?@pjs因为我不知道你在使用哪个IDE,所以我不能给出建议。大多数调试器都会使用它提供一种设置断点的机制,以及一种逐行检查代码的方法,可以检查变量。在IDE中执行此操作的详细信息由您自己掌握。我正在使用eclipse,教授@pjs@SittingBull:这就是递归的魔力。
moveDisks(.., 'C', 'A', 'B')
moveDisks(.., 'A', 'B', 'C')