初学Python:从汉诺塔问题看递归

      今天跟着廖雪峰Python教程学习到递归函数这一章节时,看到了大名鼎鼎的汉诺塔问题,然而对于用递归实现汉诺塔问题的过程还是有疑问,不能理解递归调用的过程,结合查到的一些解释写一下自己的理解。

————————————————————————————————————————————————————

什么是汉诺塔问题?

       汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。简单粗暴来上图:

                                                        初学Python:从汉诺塔问题看递归_第1张图片

先贴上Python代码然后来分析:

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)

       我们的move就是来运送盘子的工具,move把盘子n从起点a,通过缓冲区b,运送到终点c。现在有n个盘子,a,b,c三个塔,将这n个盘子抽象成最底端1个和其他的n-1个,需要用move完成的任务就是:

  • 将起点的n-1移动到缓冲区;(1)
  • 将1个移动到终点;(2)
  • 将缓冲区中n-1个移动到终点。(3)

过程(1)的实现:起点是a,终点是b,移动n-1个盘子====>move(n-1,a,c,b)

过程(2)的实现:起点是a,终点是c,移动1个盘子====>move(1,a,b,c)

过程(3)的实现:起点是b,终点是c,移动n-1个盘子====>move(n-1,b,a,c)

最后的终止条件:if n == 1:print('move',a,'-->',c)

 以上是从知乎上看到了一个基本的理解,下面通过断点运行程序看看是如何递归的。

以n=2为例:

注意此时的参数:

初学Python:从汉诺塔问题看递归_第2张图片

n=2,进入else,此时参数不变:

初学Python:从汉诺塔问题看递归_第3张图片

进入递归move(n-1,a,b,c),此时参数n变为1,回到move函数最开始执行:

初学Python:从汉诺塔问题看递归_第4张图片

重新进入if进行判断,执行n=1时的语句,打印转移路线:

初学Python:从汉诺塔问题看递归_第5张图片

此时move(2,a,b,c)递归调用的move(1,a,b,c)执行完成,返回最初的调用者move(2,a,b,c),所以这里的参数又变回了n=2,继续往下执行move(1,a,b,c):

初学Python:从汉诺塔问题看递归_第6张图片

此时n=1,重新回到move函数开始位置,进入if判断,执行打印语句:

初学Python:从汉诺塔问题看递归_第7张图片

初学Python:从汉诺塔问题看递归_第8张图片

打印后返回move(1,a,b,c),继续向下执行move(2,a,b,c),所以可以看到参数变为n=2:

初学Python:从汉诺塔问题看递归_第9张图片

move(2,a,b,c)递归调用move(1,a,b,c),重新回到函数头,进入if判断:

初学Python:从汉诺塔问题看递归_第10张图片

最后一次执行打印语句,返回调用递归的语句move(1,a,b,c),函数整体执行完成。

初学Python:从汉诺塔问题看递归_第11张图片

如果小伙伴们遇到不会的问题,百度绝对值得拥有,有很多大佬已经给出了很多经典的理解,非常有助于自己的学习。

————————————————————————————————————————————————————

参考:

https://www.cnblogs.com/tgycoder/p/6063722.html

https://www.zhihu.com/question/37152936/answer/164072324

https://www.zhihu.com/question/37152936


你可能感兴趣的:(Python)