我不懂河内算法

时间:2011-12-15 15:09:23

标签: c recursion

老实说:从今年年初(高中高中开始)直到我们终于看到递归的那一天,我一直在编程方面做得很好。 我不理解河内塔的递归代码:我似乎没有得到的具体点是目的地塔和原点之间的转换,反之亦然:

我基本上了解递归是什么,堆栈是什么,但我不明白为什么塔的顺序发生了变化。

非常感谢您的帮助。谢谢。 // N件数

    private void Déplacer(short N, string o, string i, string d)
    {
        if (N == 1)
        {
            MessageBox.Show("Move " + o + "to " + d);
            lstUn.Items.Add((lstUn.Items.Count + 1).ToString() + "-" + "Move " + o + " vers " + d);
            return;
        }


        else
        { 
        //Switch d and i
            Déplacer((short)(N - 1), o, d, i);
            lstUn.Items.Add((lstUn.Items.Count + 1).ToString() + "-" + "Déplace " + o + " vers " + d);
            MessageBox.Show("Déplace " + o + " vers " + d); //1 vers 3
            Déplacer((short)(N - 1), i, o, d);

        }

3 个答案:

答案 0 :(得分:3)

塔的顺序发生了变化,因为两个递归步骤有不同的用途。对于其中一个,目的是“将整个堆栈从A塔移动到C塔”(目标#1)。另一方面,目的是“通过将所有其他环放在B塔上”(目标#2)将底部环从A座移动到C座。

如果你看一个有3个戒指的例子,这可能是最容易理解的。最初我们有:

A (3)(2)(1)
B
C

我们希望将环从A移动到C,但为了做到这一点,我们首先需要将底环放在C上。因此,我们从目标#2开始。在目标#2中,我们需要将所有其他环移动到B上,因此当我们进入它时,我们得到目标#1,但目标塔更改为B.完成后,我们得到:< / p>

A
B (2)(1)
C (3)

现在我们有从B到C的目标#1。但是为了做到这一点,我们首先从B到C有目标#2(从B到A基本上是目标#1)。因此,基本上,目标塔会发生变化,因为每次递归步骤都会在目标#1和目标#2之间切换。

答案 1 :(得分:2)

根据河内塔的规则,你永远不能把一个更大的磁盘放在一个较小的磁盘之上。

想象一下三座塔,塔1上有三个圆盘。要将三个磁盘移动到塔3,您需要能够将最大的磁盘从塔1移动到塔3;这意味着您必须将两个较小的磁盘从塔1移动到塔2.如何将两个磁盘从塔1移动到塔2?那么,你需要将磁盘1移动到塔3;然后你可以将磁盘2移动到塔2;然后你可以将磁盘1从塔3移动到塔2.现在你可以将磁盘3移动到塔3;并且您需要将两个磁盘从塔2移动到塔3 - 这意味着您将磁盘1移动到塔1;然后磁盘2到塔3;最后是磁盘1到塔3,完成了这个过程。

这就是算法的本质。每当你需要将一些磁盘从一个塔移动到另一个塔时,你就会递归。

规则的结果是每隔一步移动最小的磁盘。

答案 2 :(得分:2)

该算法的一个很好的解释可以在http://en.wikipedia.org/wiki/Tower_of_Hanoi#Recursive_solution

中找到

注意代码几乎是这个算法的行到实现