当我们学习一门编程语言的时候,都会遇到递归函数这个问题。而学习递归的一个经典案例就是汉诺塔问题。通过这篇文章,观察移动三个盘子和四个盘子的详细过程,您不仅可以深刻的了解递归,也更加熟悉了汉诺塔的游戏的玩法。

更好的阅读体验可访问 这里

规则

有a、b、c三个柱子,a从上到下,从小到大有n个盘子。要求把a上所有盘子移动到c,一次只能移动一个盘子,且大盘子不能放小盘子上。

方法

  1. 当a上有一个盘子时,直接把该盘子移动到c。
  2. 当a上有n个盘子时(n > 1):

    先把a上n-1个盘子移动到b,

    再把a上最后一个盘子移动到c,

    再把b上所有盘子移动到c。

代码实现

def mov(n,a,b,c):
if n == 1:
# 如果a上只有一个盘子,直接把a移动到c
print(a,'-->',c)
else:
# 先把a上的n-1个盘子移动到b
mov(n-1,a,c,b)
# 再把a上最后一个盘子移动到c
mov(1,a,b,c)
# 最后把b上所有盘子(n-1个)移动到c
mov(n-1,b,a,c) num = abs(int(input('一共有几个盘子:')))
print('\n移动步骤为:')
mov(num,'A','B','C')

3个盘子的实例

  1. 先把a上的2个移动到b

    先把a上的1个移动到c

    再把a上最后1个移动到b

    再把c上仅有的一个移动到b

  2. 再把a上最后一个移动到c
  3. 再把b上的两个移动到c

    先把b上的一个移动到a

    再把b上最后一个移动到c

    再把a上仅有的一个移动到c

也就是:

A --> C

A --> B

C --> B

A --> C

B --> A

B --> C

A --> C

4个盘子的实例

  1. 先把a上的三个移动到b(套用上面三个盘子的情况,只不过之前是移动到c,现在是b)

    先把a上的2个移动到c

    先把a上的1个移动到b

    再把a上最后1个移动到c

    再把b上仅有的一个移动到c

    再把a上最后一个移动到b

    再把c上的两个移动到b

    先把c上的一个移动到a

    再把c上最后一个移动到b

    再把a上仅有的一个移动到b

  2. 再把a上最后一个移动到c
  3. 再把b上的3个移动到c(还是第一步的思路,只是换了个柱子)

    先把b上的2个移动到a

    先把b上的1个移动到c

    再把b上最后1个移动到a

    再把c上仅有的一个移动到a

    再把b上最后一个移动到c

    再把a上的两个移动到c

    先把a上的一个移动到b

    再把a上最后一个移动到c

    再把b上仅有的一个移动到c

    也就是:

    A --> B

    A --> C

    B --> C

    A --> B

    C --> A

    C --> B

    A --> B

    A --> C

    B --> C

    B --> A

    C --> A

    B --> C

    A --> B

    A --> C

    B --> C

这样就清晰的看出移动的各个步骤。

总结

再反过来分析一下,当移动一个盘子的时候只需一步就能完成,对应于代码中的

	if n == 1:
# 如果a上只有一个盘子,直接把a移动到c
print(a,'-->',c)

当移动两个盘子的时候,得需要三步才能完成。例如:把a上的两个盘子移动到c

  1. 先把a上的1个移动到b
  2. 再把a上最后1个移动到c
  3. 再把b上仅有的一个移动到c

当移动三个盘子的时候,就可以分解成先移动两个盘子,再移动一个盘子。

当移动四个盘子的时候,就可以分解为先移动三个盘子,再移动一个盘子。依次类推。。

可见当移动两个或两个以上个数盘子的时候,都只需要三步就可以完成。其中每一步又可以分解为三步,直到只剩下一个盘子的情况。对应于代码中的

	else:
# 先把a上的n-1个盘子移动到b
mov(n-1,a,c,b)
# 再把a上最后一个盘子移动到c
mov(1,a,b,c)
# 最后把b上所有盘子(n-1个)移动到c
mov(n-1,b,a,c)

所以,汉诺塔问题,你了解了吗?

参考:python下实现汉诺塔

最新文章

  1. Android IOS WebRTC 音视频开发总结(二五)-- webrtc优秀资源汇总
  2. 《JavaScript语言精粹》之函数化
  3. Redis基础知识之—— 缓存应用场景
  4. Android EventBus
  5. OpenStack网络的前世今生
  6. 中间容器 - JTabbedPane的用法的最简举例
  7. U盘开发之SSD对比
  8. ACE定时器
  9. TabControl选项卡
  10. 如何关闭eclipse对js xml的验证
  11. Hadoop 一: NCDC 数据准备
  12. hdu4678 Mine 2013 Multi-University Training Contest 8 博弈题
  13. javaWeb中URLEncoder.encode空格问题
  14. NodeJS之异常处理
  15. Linux 相关术语_002
  16. 一个比较变态的js传值,Query的bind、ajax闭包、上下文传值
  17. ubuntu16系统磁盘空间/dev/vda1占用满的问题
  18. Appium 安装详细版教程
  19. THUWC2017随机二分图
  20. python基础系列教程——Python的安装与测试:python的IDE工具PyDev和pycharm,anaconda

热门文章

  1. 爬虫-js
  2. nginx配置文件结构及location块语法规则
  3. Tomcat服务部署与Nginx负载均衡配置
  4. AtCoder Grand Contest 039 简要题解
  5. PLSQL安装过程和SCOTT用户被锁的解决方法
  6. ASP.NET的MVC请求处理流程
  7. 系统内置委托Action和func
  8. linux搜索log文件的内容
  9. golang --- fmt.printf I/O 函数格式化说明
  10. 浅析libuv源码-node事件轮询解析(2)