前言
This Series aritcles are all based on the book 《经典算法大全》; 对于该书的所有案例进行一个探究和拓展,并且用python和C++进行实现; 目的是熟悉常用算法过程中的技巧和逻辑拓展。
提出问题
河内之塔, 就是汉诺塔,背景就不介绍了, 有兴趣的搜一些, 我们在意的是解决问题本身。
游戏里有三根金刚石柱子,在一根柱子上从下往上安大小顺序摞着64片黄金圆盘。玩家需要做的是把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
分析和解释
- 需要的方法
- 递归思路
首先对于玩过的人都知道, 汉罗塔的解法是 第 N 层和 第 N-1 层是有关联的, 解决N层, 将N-1层看做一个整体进行反复调用即可。
所以我们的解答就可以是::
建立一个递归程序def Han(n, a,b,c), 其中n代表层数, abc分别代表借助于b,a把所有的盘子都移动到了C。
- 递归思路
0 递归出口 用if-else; 出口就是当这个盘子通过a–>c的过程中,最后a上只有一个盘子,直接移动a -> c即可。
Note: 这里的 a,c 是形式参数, 是相对的,有可能a,c表示的是“A”“B”两个柱子。 1, 整个递归程序解释的是一个目标,完成这样的一个目标:n个盘子的汉罗塔, a全部移动到了c。 2, 那么就可以直接想到了; 把 n-1 个盘子看做一个整体,那么达到N层a->c的目标是不是要把 n-1 移动到通过层b;也就是调用 def Han(n-1, a,c,b); 3,接着就直接在控制台中给我们展现这个步骤状态,移动最大的盘子 a -> c 所以 print (a->c) 4, 现在盘子还是b 上,最大的一个递归程序还没有结束; 实现目标 移动 n-1 个盘子从 b 通过a移动到 C。所以调用 Han(n-1, b,a,c)
常见的理解误区
- 递归程序的了解
递归程序是一种特殊的循环, 它满足无后效性, 就是说你不用管它的过程,主需要知道你的这一步和上一步的关系就行了,接着就是了解这个递归的出口; 没有出口它就会一直递归下去。往往这个复杂度是 指数阶;
代码
def Han(n, a,b,c):
if(n==1):
print (a,"move to", c)
else:
Han(n-1,a,c,b)
print (a,"move to", c)
Han(n-1,b,a,c)
Han(8,"A","B","C")
拓展和关联
- 广度拓展, 这类问题非常非常多, 民间的九连环也是这种解决思路, 有兴趣的可以玩一下。
- 深度拓展:
汉罗塔问题引出了一系列的问题和解决优化, 目的都是活跃脑洞人民的逻辑性和创造力。
- 3 层汉诺塔
后记
在后期会看看这个算法的非递归解决思路
另外会找出其他的?一系列类似的问题进行讨论和深入。
参考书籍
- 《经典算法大全》
- 维基百科