为了账号安全,请及时绑定邮箱和手机立即绑定

关于Python汉诺塔的问题,下面的代码写法不懂!!!小白啊!!!!!!

关于Python汉诺塔的问题,下面的代码写法不懂!!!小白啊!!!!!!

asdhjhg 2017-02-11 00:32:39
#coding=utf-8 #关于Python的问题 #这道汉诺塔题原理我懂了,其实就是不断在循环做同样的事,只是所谓的a,b,c这三个‘柱子’中b和c不断调换位置。但是下面的代码写法不大懂!!!小白啊!!!!!! def move(n, a, b, c):          if n==1:         print a,'-->',c         return           #if语句print之后不是就结束了吗??有同学说不加会无限循环?都print出来了还怎么无限循环呢?     else:                #这里我加了else,很多同学的代码这里都没有写else,为什么?不写不是逻辑有问题?         move(n-1,a,c,b)  #这里表示是将n-1个盘子从源柱移动至过度柱?为什么是这样写?move()为什么可以实现n-1的随意移动?         print a,'-->',c  #这里为什么又出现了print?我知道这是把最后一个移到目标柱,为什么不是和上面一样move()         move(n-1,b,a,c)  #这里和line6一样的,()里的n-1为何可以随意移动?而且a,c,b和a,b,c这种写法怎么解释?,感觉这代码为什么要这么绕....这汉诺塔的意思我都理解,可是代码写的我凌乱!!!          move(4, 'A', 'B', 'C') 请大神为我一一细答!小弟不胜感激!!!
查看完整描述

1 回答

已采纳
?
亚努人

TA贡献58条经验 获得超75个赞

这是递归的典型应用。下面通俗的说明一下,主要明白意思,就好懂了。

  def move(n, a, b, c): #这一句是定义move函数,其中n是盘子的数量,a是源柱,b是辅助柱子,c是目标柱子
if n==1:       
    print a,'-->',c
    return

这段语句的意思是,当盘子只有1个的时候,就直接输出,将那个盘子从a柱移到c柱。并且会结束代码的执行!因为n=1是递归的边界条件(当你以后学算法学到递归的时候就知道了,每个递归程序都有一个边界条件,用于结束循环,跳出代码的执行)。

另外,else可以不加,因为如果你给的n是1,自然会执行if语句,如果不是1,自然顺序执行if后面的语句,不加也是可以的。

 move(n-1,a,c,b)

从这里开始,就是函数的递归调用了(自己调用自己)。当有n个盘子的时候(n !=1),我们首先要将前面的n-1个盘子先移走,即将盘子从原柱通过目标柱移到辅助柱上,此时参数中的c实际就相当于是辅助柱了,所以有下面的语句进行路径输出

print a,'-->',c

移到辅助柱上当然是不够的,还要将辅助柱上的盘子移到目标柱去,所以下面的语句

move(n-1,b,a,c)

原先辅助柱b此时就是原柱了,将通过a作为辅助移到目标柱c上去。整个过程会重复的执行,比如最先执行的n-1,在n-1执行时,又会先将n-1个盘子的前n-1个盘子(即n-2)进行移动,以此递归,直到边界条件,当n为1时,就输出了最开始的那句话。

所以上面你有个问题是move为什么可以随意移动,原因就是递归函数自己调用自己,自己可以按照既定的规则移动,那参数的顺序改变了,每个参数代表的含义也不一样了,原来的目标柱在后续的移动步骤中可能就是辅助柱了,但移动的规则还是没变。所以递归的代码简洁难懂,就是这样的。

查看完整回答
2 反对 回复 2017-02-11
  • 亚努人
    亚努人
    你后面的理解是对的,只要n-1不是1,就会一直递归下去做n-2,n-3……至于你说的为什么代码中没有体现打印出诸如a-->b这样的路径,还是我之前跟你提到的,后面递归执行move函数的时候,参数的顺序改变了,原来的a(源柱)在后面的move中就是b(辅助柱)了,那语句中的print a->c实际上打印出来也就是诸如b->a这样的路径,这个结合实际情况,把三个柱子的角色弄清楚,打印出来的路径就没错了。
  • asdhjhg
    asdhjhg
    我今天晚上又研究了一下,我感觉我好想明白了,请看看我自己的回复!
  • asdhjhg
    asdhjhg
    大神给评阅一下!我自己得理解....
点击展开后面1
  • 1 回答
  • 0 关注
  • 3379 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信