鱼C论坛

 找回密码
 立即注册
查看: 1384|回复: 14

[已解决]汉诺塔函数----求助

[复制链接]
发表于 2018-6-11 21:57:46 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
如小甲鱼老师上课时候所讲的原理列出了递归函数表达式如下:
def hanoi_1(n,x,y,z):
    if n == 1:
        print(x,"-->",z)
    else:
        hanoi_1(n-1,x,z,y) #将n-1个盘子从x移动到y上
        print(x,"-->",z) #将最底下的最后一个盘子从x移动到z上
        hanoi_1(n-1,y,x,z) #将y上的n-1个盘子移动到z上
print(hanoi_1(3,'x','y','z'))

函数输出n=3时候,得以下表达式:
x --> z
x --> y
z --> y
x --> z
y --> x
y --> z
x --> z


疑问:
0 在函数里面else中,hanoi_1(n-1,x,z,y)      print(x,"-->",z)      hanoi_1(n-1,y,x,z)这三个式子是运行顺序是如何,是先运行print再运行第一个最后运行第三个吗?
1 在上面0表达式内,无论我怎么输出,也无法得到输出结果里面的“z --> y”这个式子啊,是我对递归函数循环的原理以及顺序理解不够吗?
2 当时小甲鱼老师在写这个式子时候,只用了三句话:#将n-1个盘子从x移动到y上    #将最底下的最后一个盘子从x移动到z上    #将y上的n-1个盘子移动到z上,这只是三个大的方向而已啊,并没有具体动作所走的顺序,然而输出的结果那么长的式子却有顺序,而且还是对的顺序,怎么也没想明白?
以上,请大牛帮忙指点,想了半天还是想不明白
最佳答案
2018-6-12 10:45:47
本帖最后由 BngThea 于 2018-6-12 10:47 编辑
木一乡 发表于 2018-6-11 23:51
我的逻辑还是理解不来
n=3时
hanoi_1(3,x,y,z)


好吧,我写一个详尽的执行步骤吧

要点: 1 递归时,一旦进入递归,后续代码暂时挂起,等回归的时候继续执行
           2 实参的不断变换


以 n==3 作为示例,请特别注意实参的变化

1  h(3,x,y,z)开始,判断if n==3不成立, 进入else

2  执行 h(2,x,z,y) #特别注意:此时形成和实参的对应关系是 x-x,y-z,z-y
        2.1 n==2,进入else,执行h(1,x,y,z) #注意实参的匹配
                print x-->z 然后返回
        2.2 print x-->y
        2.3 执行h(1,z,x,y)#注意实参的匹配
                print z-->y 然后返回
        返回到h(3,x,y,z)

3 print x-->z

4 执行 h(2,y,x,z) #特别注意:此时形成和实参的对应关系是 x-y,y-x,z-z
        2.1 n==2,进入else,执行h(1,y,z,x) #注意实参的匹配
                print y-->x 然后返回
        2.2 print y-->z
        2.3 执行h(1,x,y,z)#注意实参的匹配
                print x-->z 然后返回
        返回到h(3,x,y,z)
程序结束


从上面看来,打印结果就是紫色字体的顺序排列
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-6-11 21:59:35 | 显示全部楼层
@BngThea 大神,求助啊~~~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-6-11 22:04:15 | 显示全部楼层
木一乡 发表于 2018-6-11 21:59
@BngThea 大神,求助啊~~~~

关键在于理解递归的逻辑过程

每次遇到 hanoi_1 函数的时候,先进入函数,后面的代码暂时挂起
等到所有的递归完成后会回到刚刚挂起的地方接着往下执行

理解了上面这一点,上面的代码应该能迎刃而解了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-6-11 22:56:39 | 显示全部楼层
这题老师设的坑太大,变量用a,b,c就好理解一点,全部用x,y,z,把我们这些菜鸟的眼都看花了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-6-11 23:00:20 | 显示全部楼层
我反正是到现在都搞不懂,建议看不懂的同学直接跳过,这种变态情况一般遇不到
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-6-11 23:51:25 | 显示全部楼层
BngThea 发表于 2018-6-11 22:04
关键在于理解递归的逻辑过程

每次遇到 hanoi_1 函数的时候,先进入函数,后面的代码暂时挂起

我的逻辑还是理解不来
n=3时
hanoi_1(3,x,y,z)
n=3≠1,进入else
hanoi_1(2,x,z,y)
n=2≠1,进入else
hanoi_1(1,x,y,z)   #为什么在n=2时再进入时,x,y,z顺序变成了hanoi_1(1,x,y,z),而不是hanoi_1(1,x,z,y)
n=1,进入if
print(x->z)#此时输出的是第二次循环时的结果
print(x->y)#此时为第三次进入循环时输出的结果

n=3
hanoi(2,y,x,z)
n=2≠1,进入else
hanoi(1,y,z,x) #为什么在n=2时再进入时,x,y,z顺序变成了hanoi_1(1,y,z,x),而不是hanoi_1(1,y,x,z)
n=1,进入if
print(y->x)#此时输出的是第二次循环时的结果
print(y->z)#此时为第三次进入循环时输出的结果
hanoi(1,x,y,z)这个不知道啦
print(x->z)这个也不知道啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-6-12 08:29:15 From FishC Mobile | 显示全部楼层
myckjx 发表于 2018-6-11 23:00
我反正是到现在都搞不懂,建议看不懂的同学直接跳过,这种变态情况一般遇不到

不行啊,强迫症患者不弄明白往下学的兴趣都没了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-6-12 08:30:06 From FishC Mobile | 显示全部楼层
myckjx 发表于 2018-6-11 22:56
这题老师设的坑太大,变量用a,b,c就好理解一点,全部用x,y,z,把我们这些菜鸟的眼都看花了

网上也查了好久,还是凉凉
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-6-12 10:01:42 | 显示全部楼层
想要明白递归,最好看一下 “栈”!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-6-12 10:09:25 From FishC Mobile | 显示全部楼层
感觉你可能是在参数和参数的值上面的混乱。你试试把最后一句print语句里面的“x”,“y”,“z”改成“”a
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-6-12 10:10:26 From FishC Mobile | 显示全部楼层
改成“a”“b”“c”试试看呢,这样你可能会有助于你分析
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-6-12 10:45:47 | 显示全部楼层    本楼为最佳答案   
本帖最后由 BngThea 于 2018-6-12 10:47 编辑
木一乡 发表于 2018-6-11 23:51
我的逻辑还是理解不来
n=3时
hanoi_1(3,x,y,z)


好吧,我写一个详尽的执行步骤吧

要点: 1 递归时,一旦进入递归,后续代码暂时挂起,等回归的时候继续执行
           2 实参的不断变换


以 n==3 作为示例,请特别注意实参的变化

1  h(3,x,y,z)开始,判断if n==3不成立, 进入else

2  执行 h(2,x,z,y) #特别注意:此时形成和实参的对应关系是 x-x,y-z,z-y
        2.1 n==2,进入else,执行h(1,x,y,z) #注意实参的匹配
                print x-->z 然后返回
        2.2 print x-->y
        2.3 执行h(1,z,x,y)#注意实参的匹配
                print z-->y 然后返回
        返回到h(3,x,y,z)

3 print x-->z

4 执行 h(2,y,x,z) #特别注意:此时形成和实参的对应关系是 x-y,y-x,z-z
        2.1 n==2,进入else,执行h(1,y,z,x) #注意实参的匹配
                print y-->x 然后返回
        2.2 print y-->z
        2.3 执行h(1,x,y,z)#注意实参的匹配
                print x-->z 然后返回
        返回到h(3,x,y,z)
程序结束


从上面看来,打印结果就是紫色字体的顺序排列

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +3 收起 理由
13572044595 + 5 + 5 + 3 鱼C有你更精彩^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 2 反对 0

使用道具 举报

发表于 2018-6-12 15:23:14 | 显示全部楼层
递归要解决的问题就是,我这一层处理一个问题。然后递归给下一层,直到N层后,跳出递归。就能解决问题。汉诺塔的问题就是每层递归移动一个盘子,然后交由下一层去处理。这个时候XYZ都是存在变化的。上面已经有人说了对递归的理解可以去看堆。递归确实也是用堆来实现的。这个最好自己画图,他是一层一层嵌套的过程。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-6-12 15:43:21 | 显示全部楼层
可以把中间的参数y看成从x移到z需要经过的路径,其他的一样,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-6-12 23:18:19 | 显示全部楼层
BngThea 发表于 2018-6-12 10:45
好吧,我写一个详尽的执行步骤吧

要点: 1 递归时,一旦进入递归,后续代码暂时挂起,等回归的时候 ...


大神,我终于是懂了,可以自己递归出来了。感谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-24 19:38

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表