在 Python 函数内部,我们可以去调用其他函数。所以如果一个函数在内部调用自身,这个函数我们就称为递归函数。
汉诺塔问题源于印度一个古老传说。相传大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上并规定,任何时候,在小圆盘上都不能放大圆盘,且在三根柱子之间一次只能移动一个圆盘。如下图1所示,请问应该如何操作?
在编程语言中,如果一种计算过程的其中每一步都会用到前一步或前几步的结果,这个计算过程就可以称为递归的。而用递归计算过程定义的函数,则被称为递归函数。递归函数的应用很广泛,例如连加、连乘及阶乘等问题都可以利用递归思想来解决。而汉诺塔问题也是递归函数的经典应用。
汉诺塔问题的解决思路是:如果我们要思考每一步怎么移可能会非常复杂,但是可以将问题简化。我们可以先假设除a
柱最下面的盘子之外,已经成功地将a
柱上面的63
个盘子移到了b
柱,这时我们只要再将最下面的盘子由a
柱移动到c
柱即可。如下图2所示:
当我们将最大的盘子由a
柱移到c
柱后,b
柱上便是余下的63
个盘子,a
柱为空。因此现在的目标就变成了将这63
个盘子由b
柱移到c
柱。这个问题和原来的问题完全一样,只是由a
柱换为了b
柱,规模由64
变为了63
。因此可以采用相同的方法,先将上面的62
个盘子由b
柱移到a
柱,再将最下面的盘子移到c
柱。
以此类推,再以b
柱为辅助,将a
柱上面的62
个圆盘最上面的61
个圆盘移动到b
柱,并将最后一块圆盘移到c
柱。我们已经发现规律,我们每次都是以a
或b
中一根柱子为辅助,然后先将除了最下面的圆盘之外的其他圆盘移动到辅助柱子上,再将最底下的圆盘移到c
柱子上,不断重复此过程。
这个反复移动圆盘的过程就是递归。例如我们每次想解决n
个圆盘的移动问题,就要先解决(n-1)
个盘子进行同样操作的问题。我们先假设a
柱上只有3
个圆盘,利用 Python 进行编程实现圆盘的移动,代码如下:
def move(n, a, b, c): if(n == 1): print(a,"->",c) return move(n-1, a, c, b) move(1, a, b, c) move(n-1, b, a, c) move(3, "a", "b", "c")
函数运行结果:
a -> c a -> b c -> b a -> c b -> a b -> c a -> c