我必须对河内塔问题进行迭代解决。我试图将尾递归调用转换为迭代调用。我正在遵循我在教科书中找到的算法来改造它。我遵循这个算法,即使我的代码类似于递归变量,我的输出也不符合指定的形式。现在从书中告诉我,用迭代进行递归调用很奇怪,但是有效。
public class DemoIterative
{
public static void TowersOfHanoi(int numberOfDisks,
String startPole, String tempPole, String endPole)
{
while (numberOfDisks > 0)
{
/** MUST GO 1, 3, 2, 1 */
TowersOfHanoi(numberOfDisks - 1, startPole, endPole, tempPole);
System.out.println(startPole + " -> " + endPole);
numberOfDisks = numberOfDisks - 1;
startPole = tempPole;
tempPole = startPole;
}
}
public static void main(String[] args)
{
DemoIterative demoIterative = new DemoIterative();
System.out.println("Enter amount of discs: ");
Scanner scanner = new Scanner(System.in);
int discs = scanner.nextInt();
demoIterative.TowersOfHanoi(discs, "A", "B", "C");
} // end of main
} // end DemoIterative
A到C, A到B, C到B, A到C, B到B, B到C, B到C
A到C, A到B, C到B, A到C, B到A, B到C, A到C
当numberOfDisks大于0时,将磁盘从startPole移动到endPole,numberOfDisks--,交换tempPole和startPole的内容。
现在这可能吗?如果是这样,我的算法是否有问题,或者我打错了?
答案 0 :(得分:0)
您的算法存在问题。对于您自己对此的理解最重要的是,在例程的顶部打一个 print 语句并打印出参数。同时在循环底部插入一个以帮助跟踪执行情况。
总结一下,我认为您不了解您创建的调用树,我认为您应该对其进行跟踪以查看。有些应用程序将使用这样的树,但我认为这不是你想要的这个任务。
有几个结构性问题。首先,当你到达循环的底部时,你设置 startPole = tempPole ,然后用无用的作业返回 - 这会消除旧的 startPole 值;它没有交换它们。
接下来,你的循环+递归结构很奇怪。首先,你使用 while 循环,其中语义清楚地表明了 for - 你知道当你进入循环时你将迭代多少次。当你第一次使用5个磁盘调用它时,numberOfDisks(我称之为N)= 5次迭代将循环5次。每次迭代分别以N = 4,3,2,1再现。
现在,N = 4实例也会这样做:用N = 3,2,1重复出现。这样就可以在N = 3时得到两个实例。接下来,您将在N = 2处获得三个实例,并且在N = 1时获得四个,总共 11 调用您的函数。由于其中只有四个涉及移动一个磁盘堆栈(对于一个5个磁盘的塔,你还需要几个磁盘),我认为你已经错误地实现了你想到的任何东西。