汉诺塔
汉诺塔介绍
汉罗塔游戏简单来说就是,有三根柱子(记作ABC),A柱子上有从小到大的若干个圆盘,我们要怎么把A柱子上的这若干个圆盘全部挪到C,并且保证顺序还是从小到大。 规则是:挪的过程中大圆盘不能放在小圆盘上面。
图解一下(来自参考资料)
可以看到如果只有一个圆盘我们可以直接挪到C。
A -> B
有两个的话先把上面的圆盘挪到B,然后把最下面的圆盘挪到C,再把B的圆盘挪到C。(重点理解)
A -> B
A -> C
B -> C
有三个的话我们也得把最下面圆盘上面所有的圆盘挪到B,把最下面的挪到C,然后再把B的圆盘挪到C。
A(n-1) -> B
A -> C
B -> C
思路
可以看到有两个和三个盘子的时候思路是一样的。我们都是要先把除最下面盘子以外的所有盘子挪到B,然后最大盘子挪到C,然后再把B的盘子挪到C,齐活。 这样的话我们可以分析出不管有多少盘子,第一步我都是得把除最大盘子以外的挪到B,然后最大盘子挪到C,然后再把B的盘子挪到C。记作
A(n-1) -> B
A -> C
B -> C
先上代码(可能有些难理解)
public static void hanoiTower(int num, char a,
char b, char c) {
// 如果只有一个盘
if (num == 1) {
System.out.println("第1个盘" + a + "=>" + c);
} else {
hanoiTower(num - 1, a, c, b);
// 把最下面的盘a - c
System.out.println("第" + num + "个盘
" + a + "=>"+ c);
// 把b所有移动到c 过程使用a
hanoiTower(num - 1, b, a,c);
}
}
加上递归的思路
在这里我们认为只有两种情况 第一种情况 只有一个盘子 那就直接从第一个挪到第三个, 如果是两个或者两个以上的话 先把n-1个盘子挪到B,然后把 n挪到C 然后把B的盘子挪到C。
先第一个递归走到底 这个时候就相当于只有一个盘子了,跟据递归的次数决定放在B还是C。然后 回溯到上一层,此时有两个盘子在上一层时第一个盘子已经被放到B或C ,如果上一个盘子放在B,根据规则我们就会把这个放到C柱子反之放到B柱子,再进行最下面的那个递归,把B放到C。 然后一层层的回溯。
分析
递归的细节不要去深究,当初我就想着这递归是怎么实现的,细节是啥,就想在脑子里一步一步的回溯出来,但是因为里面有两个递归进行穿插,所以不好想。
我们首先知道总体思想就是分为三步,第一步是(n-1)的柱子挪到B,n挪到C,再把B挪到C。在进行第一步时我们会递归找到最上面的那一个,然后把最上面的挪到B或者C,为什么是B或者C呢,因为我们也不确定我们有多少个,第一个该放到哪。递归的作用就是帮我们把问题递出去,然后归来的是结果。(这里想不明白分析第二张图片和第三张),然后在把第现在这个圆盘放到B或C上,下面递归的作用就是判断B有没有圆盘有的话把B的圆盘放到C,这也是一个递归问题,因为回溯到后面可能B上也会放很多盘子,我们就得递归(上面得思想)把B的盘子放到C。
总结
先宏观的去看这个问题,然后一点点的深入,不要钻牛角尖。
参考资料
传送
https://www.cnblogs.com/starry-skys/archive/2020/03/23/12555829.html
秃头萌新一枚,多多关照。