Loading

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

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

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

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

比如汉诺塔的打印:

    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)是已知的,我们已经求过了)。

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

🐳🐳🐳🐳🐳🐳

posted @ 2021-06-04 12:17  KeBoom  阅读(173)  评论(0编辑  收藏  举报