河内的塔递归/迭代混合

时间:2016-09-26 20:58:00

标签: java algorithm recursion iteration

我必须对河内塔问题进行迭代解决。我试图将尾递归调用转换为迭代调用。我正在遵循我在教科书中找到的算法来改造​​它。我遵循这个算法,即使我的代码类似于递归变量,我的输出也不符合指定的形式。现在从书中告诉我,用迭代进行递归调用很奇怪,但是有效。

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的内容。

现在这可能吗?如果是这样,我的算法是否有问题,或者我打错了?

1 个答案:

答案 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个磁盘的塔,你还需要几个磁盘),我认为你已经错误地实现了你想到的任何东西。