注: 本系列仅为个人学习笔记,学习内容为《算法小讲堂》(视频传送门),通俗易懂适合编程入门小白,需要具备python语言基础,本人小白,如内容有误感谢您的批评指正
汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
首先考虑A座最下面的盘子移动到C座,如果能将上面的63个盘子从A座借助C座移到B座,再将63个盘子从B座借助A座移到C座,那任务即可完成,以此类推~直到仅有一个盘子的情形,则将一个盘子从一个座移动到另一个座,问题也就全部得到解决。而这就是典型的递归问题(可以理解为套娃,代码是从最大的娃往里一层一层套到最小的那个,输出是把最小到最大的一层层摆出来)
由以上描述我们可以知道递归算法的一些特征,为了求解规模为 N 的问题,应先设法将该问题分解成一些规模较小的问题,从这些较小问题的解可以方便地构造出大问题的解。同时,这些规模较小的问题也可以采用同样的方法分解成规模更小的问题,并能从这些规模更小的问题的解中构造出规模较小问题的解。特别地,当 N=1 时,可直接获得问题的解。
现在我们来找出解决问题的方法,定义一个递归函数hanno(N,A,B,C),该方法表示将N个盘子从A座借助B座移动到C座,盘子的初始个数为N。具体步骤为:
- 若 A 座上只有 1 个盘子,此时 N=1,则可直接将盘子从 A 座移动到 C 座上,问题得到解决。
- 若 A 座上有 1 个以上的盘子,即 N>1,此时需要再考虑 3 个步骤:
1)先将 N-1 个盘子从 A 座借助 C 座移动到 B 座上。显然,这 N-1 个盘子不能作为一个整体移动,而是要按照要求来移动。此时,可递归调用函数 hanoi(N-1,A,C,B)。需要注意的是,这里借助 C 座将 N-1 个盘子从 A 座移动到 B 座,A 是源,B 是目标。
2)将 A 座上剩下的第 N 个盘子移动到 C 座上。
3)将 B 座上的 N-1 个盘子借助 A 座移动到 C 座上。此时,递归调用函数 hanoi(N-1,B,A,C)。需要注意的是,这里借助于 A 座将 N-1 个盘子从 B 座移动到 C 座,B 是源,C 是目标。
完成了这 3 步,就可以实现预期的效果,在 C 座上按照正确的次序叠放好所有的盘子。
代码实现如下:
def hanno(N,A,B,C):
if N==1:
print('将盘子1从{}移到{}'.format(A,C))
else:
hanno(N-1,A,C,B)
print('将盘子{}从{}移到{}'.format(N,A,C))
hanno(N-1,B,A,C)
if __name__=='__main__':
hanno(3,'A','B','C')
输出结果:
将盘子1从A移到C
将盘子2从A移到B
将盘子1从C移到B
将盘子3从A移到C
将盘子1从B移到A
将盘子2从B移到C
将盘子1从A移到C
注:递归这里不能简单的认为A,C一直等于最开始传入的实参,本篇参考汉诺塔(图文结合),超好理解,可自行阅读原文