河内的塔;递归方法意味着方法永远不会完成?

时间:2013-11-12 00:47:30

标签: java recursion towers-of-hanoi

public class han {

    public static void main(String[] args) {
        hanoi(5, "A", "B", "C");   
    }

    private static void hanoi (int n, String from, String other, String to) {
        if (n==0){
            return;
        }
        if (n>0){
            hanoi(n-1, from, to, other); //comment
            System.out.printf("Move one disk from %s to %s \n ", from, to);
            hanoi(n-1, other, from, to); //comment
        }
    }

}

我正在学习递归,经典的例子是河内塔。然而,我有点难过,上面的代码片段中有注释的行。

如果方法在第一个注释代码重新启动,该程序如何到达第二个注释代码?类似下面的内容来说明:

1: some junk
2: goto 1
3: more junk

如果3重新启动此功能,它怎么能达到2?同样适用于河内之塔片段:它如何达到第二个评论代码?

2 个答案:

答案 0 :(得分:3)

它不会重启。你可以把它想象成一棵正在种植新树枝和树叶的树。

在您第一次打电话给hanoi()后,它会一次又一次地调用自己,直到它达到基本情况为止:

if (n==0){
    return;
}

这意味着当第一个注释行的调用在其所有分支中到达基本情况时,它将返回到该点并继续执行。

如果没有基本情况(某些条件语句最终使你的函数返回),你的函数将陷入无限循环。

我认为河内之塔虽然是经典但很难理解你应该从一个更简单的问题开始,比如计算fibonacci sequence或实用算法的元素:depth first search

如果你无法理解递归,我可以建议The Little Schemer这是一本关于这个主题的精彩书。我很难想象会有更好更彻底的解释。

答案 1 :(得分:2)

当递归函数完成时,它会在这里调用的相同位置恢复,这是一个小图,只打印3-1中的数字

递归方法

public static void printRecursive(int n)
{
    if(n ==0)
        return;
    system.out.println(n);
    print(n-1);
    //continue execution here
}

迭代方法

public static void printIterative()
{
    if(n == 0)
    {
        return;
    }
    else
    {
        system.out.println(n);
        int n2 = n-1;
        if(n2 == 0)
        {
            return
        }
        else
        {
            system.out.println(n2);
            int n3 = n2-1;
            if(n3 ==0)
            {
                return;
            }
            else
            {
                system.out.println(n3);
                int n....
                ...
                ...
            }
            //continue....
        }
        //continue exectuion from second call
    }
    //continue exection from first call
}

基本上我在第二种方法中所做的就是复制并通过连续调用直接内联打印而不是调用自身。

递归调用将从进行递归调用的地方继续运行。这可能很难包容,但非常值得理解