汉诺塔问题——对于递归过程的解释
我们只看看最基础的汉诺塔问题吧,左神的进阶问题就算了。。。😃
很多人都将汉诺塔是什么,解题流程,然后一个代码就结束。
可是我对汉诺塔递归过程总是很迷惑,感觉很抽象,以下是我的理解。
比如汉诺塔的打印:
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)是已知的,我们已经求过了)。
如此我们能否就能够理解一点汉诺塔的递归过程了呢?
🐳🐳🐳🐳🐳🐳
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库