码迷,mamicode.com
首页 > 其他好文 > 详细

汉诺塔问题——对于递归过程的解释

时间:2021-06-04 19:29:33      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:stack   lse   int   resolve   树遍历   解释   打印   else   void   

我们只看看最基础的汉诺塔问题吧,左神的进阶问题就算了。。。??

很多人都将汉诺塔是什么,解题流程,然后一个代码就结束。

可是我对汉诺塔递归过程总是很迷惑,感觉很抽象,以下是我的理解。

比如汉诺塔的打印:

    public void hanoi(int n) {
        if (n > 0) {
            func(n, "left", "mid", "right");
        }
    }
    
    public void func(int n, String from, String mid, String to) {
        if (n == 1) {
            System.out.println("move from " + from + " to " + to);
        } else {
            // 将左边n-1移动到中间
            func(n - 1, from, to, mid);
            // 将左边最后一个移动右边
            func(1, from, mid, to);
            // 将中间的n-1移动的右边
            func(n - 1, mid, from, to);
        }
    }

栈中移动:

      public static void resolve(int n, Stack<Integer> a, Stack<Integer> b, Stack<Integer> c) {
            if (n==0) return;
            resolve(n-1, a, c, b);
            c.push(a.pop());
            resolve(n-1, b, a, c);
      }

我一直搞不懂这递归函数怎么写出来的,因为我用栈的思维一致向下递归,回溯,总是很难想出来。

但是二叉树的前中后序遍历,递归形式就非常好想象,正好二叉树向下递归的过程,然后在回溯,他的过程跟二叉树遍历过程就是一模一样。

但是对于汉诺塔问题的递归过程,我总是很难想象。

所以我从斐波那契的递归过程入手,斐波那契求f(n),比如说就f(10)吧,我们总要先递归到f(1),f(2),然后回溯可求得f(3),然后有了f(3),f(2),回溯求得f(4),然后一直向上回溯就能求的f(10)

那么对于汉诺塔问题呢?对于f(1)我们直接从left到right,对于f(2)我们left到mid,left到right,mid到right。我们把它看做基础条件。那么我们求f(3),目前left上有3个圆盘,我们先要将left最上面2个原盘移动到mid(对于移动2个圆盘是基础条件!!是已知的!!),然后将left最后一个圆盘移动到right(移动一个圆盘也是基础条件!!是已知的!!),然后将mid上的两个圆盘移动到right(移动两个圆盘是基础条件!!!是已知的!),最终我们就能得到f(3)!!

那么我们现在知道f(3),那就能求f(4)了!!!

求f(4),进来之后执行f(3),将left上面3个圆盘放到mid(f(3)是已知的,我们已经求过了),然后将left最后一个圆盘放到right,然后将mid上3个圆盘放到right(f(3)是已知的,我们已经求过了)。

如此我们能否就能够理解一点汉诺塔的递归过程了呢?

????????????

汉诺塔问题——对于递归过程的解释

标签:stack   lse   int   resolve   树遍历   解释   打印   else   void   

原文地址:https://www.cnblogs.com/keboom/p/14849047.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!