汉诺塔的原理很简单,有三个柱子,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')
运行结果为