汉诺塔的原理很简单,有三个柱子,A柱上有一些圆盘,圆盘大小不一,小的在上面,大的在下面。

目标是将圆盘一个一个地移动到C柱,B柱是临时柱子,可以临时存放圆盘。

要求是无论在哪根柱子上,小圆盘下面必须是大圆盘。

 

 

如果用代码实现,用递归是最好不过了,但是要写出代码来,也不是件容易的事情。

 

操作其实很简单,把A柱上的圆盘放到C柱上,可是A柱上有多少个圆盘呢,不确定。

假设只有一个圆盘,n=1

是最简单的,直接从A柱挪到C柱即可,B柱根本用不到。

步骤如下:

a -> c

那如果是2个呢?假设有一个小圆盘和一个大圆盘,n=2

那么需要先将小圆盘从A柱移到B柱上,然后将大圆盘从A柱移到C柱上,最后将B柱上的小圆盘移到C柱上

步骤如下:

a -> b
a -> c
b -> c

如果是3个呢?

。。。ok,不再继续描述。

 

重点来了(敲黑板),无论A柱上圆盘数量有多少个(n>2),都可以把这么多圆盘当成是2个圆盘来操作,即上面一堆圆盘算一个,最下面那个最大的圆盘算一个,此时将这2个圆盘移到C柱,需要操作的步骤就与n=2时完全一致了。

 

 

步骤如下:

a -> b
a -> c
b -> c

是不是似曾相识?

那么以此为核心,来尝试实现它。

 

先定义一个方法move,需要4个参数,一个是圆盘数量n,另外3个参数分别代表起始桩,临时桩,目的桩3个柱子,用a,b,c表示

def move(n,a,b,c):

当只有一个圆盘的时候,即n=1时,操作最简单,打印从A柱到C柱这一步骤

if n == 1:
  print(a + '->' + c)

当n不等于1时,即n>=2时,都当作2个圆盘来操作,先将n-1个圆盘当作一个合并的圆盘从A柱移动到B柱

else:

  move(n-1, a, c, b)

移动完后,此时A柱上只有一个圆盘了,所以它的圆盘数量是1,从A柱移到C柱

move(1, a, b, c)

最后将B柱上的“一堆圆盘”(n-1个)作为一个圆盘从B柱移到C柱

move(n-1, b, a, c)

最终代码如下:

 1 def move(n,a,b,c):
 2     '''
 3     :param n: 盘数量
 4     :param a: 起始桩
 5     :param b: 临时桩
 6     :param c: 目的桩
 7     '''
 8     if n == 1:
 9         print(a + '->' + c)
10     else:
11         move(n-1, a, c, b)
12        
13         move(1, a, b, c)
14         
15         move(n-1, b, a, c)
16 
17 if __name__ == '__main__':
18     move(3,'a','b','c')

运行结果为