Hanoi Tower汉诺塔问题函数递归算法分析及相应python代码
2017-12-22 09:38
381 查看
函数递归应用中最经典的案例要算是汉诺塔(Hanoi Tower)问题了。
题目如下:
相传印度有一个梵塔,塔内有三个座A、B、C。A座上有n个盘子,盘子从上到下一个比一个大,最大的在下面。目标:僧人要把这些盘子从A座移到C座,中间借用B座,每次只能移动一个盘子,并且在移动过程中必须始终保持
大盘在小盘的下面。计算不同数量时的移动过程。
分析,既然有第n个盘子,那就有第1个盘子,把盘子从上到下顺序编号为1....n
那么,最底下的第n号盘子就交给方丈了,其他盘子由大师兄全权负责,具体是:
由大师兄负责先把前面n-1个盘子由A移动到B,然后方丈把第n号盘子轻松从A移到C,然后再由大师兄负责把前面n-1个盘子由B移动到C即完成;
那么,大师兄也想了一下,自己就只管第n-1号盘子由A移到B,其他n-2个盘子全交给二师兄去办,具体是:
由二师兄负责先把前面n-2个盘子由A移动到C,然后大师兄轻松把第n-1号盘子从A移到B,然后再由二师兄负责把前面n-2个盘子由C移动到B即完成;
那么,二师兄又想了一下,人家都可以那样干,自己也可以找人啊,于是,每个人都这样想,最后方案简化为每个人都只需做三步:
让别人把其他盘子移到临时座上,自己把最后一个盘子移到自己的目标座,让别人把其他盘子从临时座上移到目标座
这样就形成了递归,每次函数内只做这三件事。
但是递归必须有一个终止条件,终止条件就是最后一个小师弟发现自己就是最后一个了,n=1,那没法再找别人了!自己把盘子乖乖移到目标座吧,没办法了,就相当于本来就只有一个盘子,直接从A移到C,直接返回并结束。
用python代码实现如下:
def hanoi(n, a, b, c):
if n == 1:
print("[%02d]:%s->%s" % (n, a, c))
return
hanoi(n - 1, a, c, b)
print("[%02d]:%s->%s" % (n, a, c))
hanoi(n - 1, b, a, c)
hanoi(3,"a","b","c")
print("done!")
结果如下:
[01]:a->c
[02]:a->b
[01]:c->b
[03]:a->c
[01]:b->a
[02]:b->c
[01]:a->c
done!
加上步数显示,优化代码如下:
cnt = 0
def hanoi(n, a, b, c):
"""
print move info
:param n: the plate number
:param a: the first stick label
:param b: the second stick label
:param c: the third stick label
:return: null
"""
global cnt
if n == 1:
cnt += 1
print("No.%03d [%02d]:%s->%s" % (cnt, n, a, c))
return
hanoi(n - 1, a, c, b)
cnt += 1
print("No.%03d [%02d]:%s->%s" % (cnt, n, a, c))
hanoi(n - 1, b, a, c)
hanoi(3,"a","b","c")
print("done!")结果如下:
No.001 [01]:a->c
No.002 [02]:a->b
No.003 [01]:c->b
No.004 [03]:a->c
No.005 [01]:b->a
No.006 [02]:b->c
No.007 [01]:a->c
done!
题目如下:
相传印度有一个梵塔,塔内有三个座A、B、C。A座上有n个盘子,盘子从上到下一个比一个大,最大的在下面。目标:僧人要把这些盘子从A座移到C座,中间借用B座,每次只能移动一个盘子,并且在移动过程中必须始终保持
大盘在小盘的下面。计算不同数量时的移动过程。
分析,既然有第n个盘子,那就有第1个盘子,把盘子从上到下顺序编号为1....n
那么,最底下的第n号盘子就交给方丈了,其他盘子由大师兄全权负责,具体是:
由大师兄负责先把前面n-1个盘子由A移动到B,然后方丈把第n号盘子轻松从A移到C,然后再由大师兄负责把前面n-1个盘子由B移动到C即完成;
那么,大师兄也想了一下,自己就只管第n-1号盘子由A移到B,其他n-2个盘子全交给二师兄去办,具体是:
由二师兄负责先把前面n-2个盘子由A移动到C,然后大师兄轻松把第n-1号盘子从A移到B,然后再由二师兄负责把前面n-2个盘子由C移动到B即完成;
那么,二师兄又想了一下,人家都可以那样干,自己也可以找人啊,于是,每个人都这样想,最后方案简化为每个人都只需做三步:
让别人把其他盘子移到临时座上,自己把最后一个盘子移到自己的目标座,让别人把其他盘子从临时座上移到目标座
这样就形成了递归,每次函数内只做这三件事。
但是递归必须有一个终止条件,终止条件就是最后一个小师弟发现自己就是最后一个了,n=1,那没法再找别人了!自己把盘子乖乖移到目标座吧,没办法了,就相当于本来就只有一个盘子,直接从A移到C,直接返回并结束。
用python代码实现如下:
def hanoi(n, a, b, c):
if n == 1:
print("[%02d]:%s->%s" % (n, a, c))
return
hanoi(n - 1, a, c, b)
print("[%02d]:%s->%s" % (n, a, c))
hanoi(n - 1, b, a, c)
hanoi(3,"a","b","c")
print("done!")
结果如下:
[01]:a->c
[02]:a->b
[01]:c->b
[03]:a->c
[01]:b->a
[02]:b->c
[01]:a->c
done!
加上步数显示,优化代码如下:
cnt = 0
def hanoi(n, a, b, c):
"""
print move info
:param n: the plate number
:param a: the first stick label
:param b: the second stick label
:param c: the third stick label
:return: null
"""
global cnt
if n == 1:
cnt += 1
print("No.%03d [%02d]:%s->%s" % (cnt, n, a, c))
return
hanoi(n - 1, a, c, b)
cnt += 1
print("No.%03d [%02d]:%s->%s" % (cnt, n, a, c))
hanoi(n - 1, b, a, c)
hanoi(3,"a","b","c")
print("done!")结果如下:
No.001 [01]:a->c
No.002 [02]:a->b
No.003 [01]:c->b
No.004 [03]:a->c
No.005 [01]:b->a
No.006 [02]:b->c
No.007 [01]:a->c
done!
相关文章推荐
- python机器学习-预测分析核心算法3-2代码在python3下运行遇到的一些问题
- 汉诺塔问题递归算法分析
- HEVC码率控制算法研究与HM相应代码分析(三)——算法及代码分析
- H.264码率控制算法研究及JM相应代码分析(三)
- 【算法设计与分析】递归与分治----2.4 排列问题
- MIT Python 第四课函数抽象与递归简介 函数调用与原代码的区别
- 汇编语言实现递归阶乘算法代码分析(8)
- 全排列问题算法分析与实现(递归、非递归)
- x264代码剖析(十一):核心算法之宏块分析函数x264_macroblock_analyse()
- x264代码剖析(十一):核心算法之宏块分析函数x264_macroblock_analyse()
- 棋盘覆盖问题算法分析与实现(递归)
- python算法和数据结构笔记--汉诺塔问题超详细递归过程图解(堆栈数据结构)
- 折半查找实现算法二(递归办法)PS:编译后有一个warning,但不影响结果,代码设计上应该还有些问题
- 求子集问题算法分析与实现(递归、非递归)
- atof()函数详解----NOI2.2基本算法之递归和自调用函数 逆波兰表达式 分析
- 常用算法的递归实现问题分析(针对《数据结构与程序设计》by Robert.L.Kruse)
- H.264码率控制算法研究及JM相应代码分析(二)
- 用递归法:设计算法求解汉诺塔问题,并编程实现。 (1) Hanoi(汉诺)塔问题分析 这是一个古典的数学问题,是一个用递归方法解题的典型例子。问题是这样的:古代有一个梵塔,塔内有3个座 A,B,C
- 利用Python的内嵌函数和递归研究汉诺塔问题
- 算法 最近对问题完整代码分析