1、什么是汉诺塔?
汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
2、转化为数学问题
如下图所示,从左到右有A、B、C三根柱子,其中A柱子上面有从小叠到大的n个圆盘,现要求将A柱子上的圆盘移到C柱子上去,期间只有一个原则:一次只能移到一个盘子且大盘子不能在小盘子上面,求移动的步骤。
解:
(1) n = 1
第1次 1号盘 A–>C 一共移动 1 次
(2) n = 2
第1次 1号盘 A–>B
第2次 2号盘 A–>C
第3次 1号盘 B–>C 一共移动 3 次
(3)n = 3
第1次 1号盘 A–>C
第2次 2号盘 A–>B
第3次 1号盘 C–>B
第4次 3号盘 A–>C
第5次 1号盘 B–>A
第6次 2号盘 B–>C
第7次 1号盘 A–>C 一共移动 7 次
不难发现规律:
1个圆盘的移动次数为
2个圆盘的移动次数 为
3个圆盘的移动次数 为
……
n个圆盘的次数 2的n次方减1
故:移动次数为:
3、python实现及解析
仔细分析上面的步骤,可以总结 实现汉诺塔可以简单分为三个步骤:
第一步: 把n-1个盘子由A 移到 B;
第二步: 把第n个盘子由 A移到 C;
第三步: 把n-1个盘子由B 移到 C;
说到这里,我们先亮出我们的完整python代码:
# 利用递归函数移动汉诺塔: n代表A柱上的盘子数
def move(n, a, b, c):
if n == 1:
print('move', a, '-->', c)
else:
move(n-1, a, c, b)
move(1, a, b, c)
move(n-1, b, a, c)
print('利用递归函数移动汉诺塔步骤:')
move(3, 'A', 'B', 'C')
按照上面实现汉诺塔的三个步骤,我们来一步步分析代码
1、move(n-1, a, c, b)
将A柱上的上面n-1个小圆盘通过C柱全部移动到B柱上去;
2、move(1, a, b, c)
第一步执行完后,此时A柱上只剩下最大的那个盘子,第二步就是将剩下的这个最大的盘子移动到C柱上;
3、move(n-1, b, a, c)
将B柱上的n-1个小圆盘通过A柱全部移动到C柱上去;
每一步判断n是否为1,若为1,打印内容,停止递归。
接下来,我们以n=3为例,详细写出程序运行的每一步
move(3, 'A', 'B', 'C') #将A柱上的上面n-1=2个小圆盘通过C柱全部移动到B柱上去
n=3: #判断n是否为1后,执行n=3时,else后的第一个move,进行递归
move(2, 'A', 'C', 'B')
n=2: #执行n=2时,else后第一个move进行一个递归
move(1, 'A', 'B', 'C')
n=1: #n=2的第一个move递归完成,打印结果;
print('move', 'A',-->, 'C')
move(1, 'A', 'C', 'B') #执行n=2时,else后第二个move进行递归;
print('move', 'A',-->, 'B')
move(1, 'C', 'A', 'B') #执行n=2时,else后第三个move进行递归;
print('move', 'C',-->, 'B')
move(1, 'A', 'B', 'C') #执行n=3时,else后第二个move进行递归;
print('move', 'A',-->, 'C')
move(2, 'B', 'A', 'C') #执行n=3时,else后第三个move进行一个递归
n=2:
move(1, 'B', 'C', 'A')
n=1: #n=2的第一个move递归完成,打印结果;
print('move', 'B',-->, 'A')
move(1, 'B', 'A', 'C') #执行n=2时,else后第二个move进行递归;
print('move', 'B',-->, 'C')
move(1, 'A', 'B', 'C') #执行n=2时,else后第三个move进行递归;
print('move', 'A',-->, 'C')
end
最后,我们运行一开始给出的代码,检查下我们的分析结果是否正确:
以上内容是自己在学习python过程中遇到的递归函数及在汉诺塔问题上的应用,如有不当地方还望批评指出,大家共同提高!