汉诺塔问题——对于递归过程的解释
我们只看看最基础的汉诺塔问题吧,左神的进阶问题就算了。。。😃
很多人都将汉诺塔是什么,解题流程,然后一个代码就结束。
可是我对汉诺塔递归过程总是很迷惑,感觉很抽象,以下是我的理解。
比如汉诺塔的打印:
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)是已知的,我们已经求过了)。
如此我们能否就能够理解一点汉诺塔的递归过程了呢?
🐳🐳🐳🐳🐳🐳