对汉诺塔递归算法的理解(图解,附完整代码实现)

前情提要:

首先说一下汉诺塔游戏的规则:如下图所示,有三个柱子A,B,C,我们要做的是把A柱的所有圆盘,全部转移到C柱上,转移时遵循的规则如下:

1、每次只能移动一个圆盘

2、所有的大圆盘必须在小圆盘的下面

 过程分析

首先假设只有一个圆盘,我们将其编号为1,如下图所示,那么这时候只需要将A直接移到C即可:

再假设有两个圆盘,我们看到移动过程如下:

步骤1:先将1号盘从A移动到B;

步骤2:再将2号盘从A移动到C;

步骤3:最后将1号盘从B移动到C,完成转移。

好了,请读者有点耐心,我们再看看三个圆盘的转移过程是怎样进行的:(此处用文字进行描述,请读者发挥想象)

首先三个圆盘放在A柱上,按从上到下的顺序依次编号为1,2,3(最小的为1,最大的为3),我们先不考虑3号盘,而只考虑上面两个小一点的圆盘(编号1,2),而此前我们已经分析了两个圆盘的移动过程,那么这两个圆盘该移动到哪根柱子呢?目前只有B柱,C柱可选,而C柱肯定不行,因为C柱是目标柱,那么我们只能把1,2号盘从A柱移动到B柱,借助C柱,则移动过程为:A->C, A->B,C->B。此时,1,2号盘已经到达B柱,再把最大的三号盘,直接移到C柱。此时工作快要完成了,目前的状态为:1,2号盘在B柱,3号盘已到达目的柱C柱,再接下来,把1,2号盘将B柱移动到C柱,转移工作就彻底结束,借助A柱,转移过程为:B->A,B->C,A->C。

通过上面第一段加红的文字,我们可以知道,A是作为起始柱,B作为目标柱,C作为辅助柱,通过第二段加红文字,我们可以知道,B是作为起始柱,A作为辅助柱,C作为目标柱。

那么此时,函数的写法,在脑海里大概就有了形状

 函数定义

根据上面的分析,我们知道,函数的参数,有盘子,A,B,C三个柱子,所以,函数的签名为:move(n, a, b, c)。其中n表示圆盘的个数,a表示起始柱,b表示辅助柱,c表示目标柱。

根据上面对三个圆盘的分析,可得函数定义如下(Python代码):

1 def move(n, a, b, c):
2     if n == 1:
3         print a + '-->' + c
4         return
5     move(n - 1, a, c, b)
6     print a + '-->' + c
7     move(n - 1, b, a, c)

代码解释:

  当n=1时,即当只有一个圆盘时,直接输出a -> c,即将圆盘从A移动到C(对应第2,3行代码)

  当n>1时,就先处理前n-1个圆盘,将前n-1个圆盘从a移动到b柱,借助c柱(对应第5行代码),然后将第n个圆盘从a柱移动到c柱(对应代码第6行),最后将剩下的n-1个圆盘,将b柱移动到c柱,借助a柱(递归思想,请读者联合上面对三个圆盘的分析仔细斟酌)

调用代码如下:(4个圆盘)

1 move(4, 'A', 'B', 'C')

结果如下:

A-->B
A-->C
B-->C
A-->B
C-->A
C-->B
A-->B
A-->C
B-->C
B-->A
C-->A
B-->C
A-->B
A-->C
B-->C


 

posted @ 2019-01-09 16:18  HeZhengfa  阅读(7081)  评论(0编辑  收藏  举报