鱼C论坛

 找回密码
 立即注册
查看: 4888|回复: 5

[技术交流] 关于第024课时,递归函数:汉诺塔的理解

[复制链接]
发表于 2021-4-12 21:26:39 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 非凡 于 2021-4-12 21:32 编辑

        今天视频学到了第24课时,13分钟的课我却用了3-4个小时去理解汉诺 是不是太衰。。。。。。
        开始就是觉得不理解,但是连不理解哪里都不知道,后来百度了很多关于“递归函数汉诺塔”的博客文章,依然没解决自己不理解的点。
不过倒是知道自己是哪里不理解了。。。。。
       
        之前一直不能理解的是,hanoi()函数内部,调用自身函数时,x,y,z三个参数的顺序,想着虽然汉诺塔可以简化成先将n-1个块从x放到y,然后将第n个块放到z,最后将n-1个块从y放到z。以上是hanoi函数递归第一层的执行步骤,而当递归第二层的以及第三第四层时,这些(n-2),(n-3)个块已经不是在x柱上了,即便(n-2)或(n-3)就等于1,那”(n-1)块从 起始柱(a)——>目标柱(b)“就已经是错了,为什么后面没有出错呢?
        其二不理解的是下面函数标红的问题。
如下:
else:
        hanoi(n-1 , x , z , y)                #将前n - 1个盘子从x移动到y上,借助z
        #这里为什么是x,z,y的顺序?
        print(x , '-->',z)                        #将x最后一个盘中移动到z上
        hanoi(n-1 , y , x , z)                #将前n - 1个盘子从y移动到z上,借助x
        #这里为什么就又变成是y,x,z的顺序了?

        就这两个困惑我花几个小时去想、验证、组织语言文字归总成笔记。望各位大佬能指正,莫笑我就好了。

小甲鱼视频课上关于汉诺的运算过程的讲解我就不放这里来了,视频上没有讲到我困惑的点(是不是我困惑的这个点,本来是什么难理解的地方?所以就不讲了

        视频课上的函数,此处调用函数的时候,我特意用了a,b,c而没有同视频上用xyz
def hanoi(n,x,y,z):
    if n == 1:
        print(x , '-->' , z)
    else:
        hanoi(n-1 , x , z , y)                #将前n - 1个盘子从x移动到y上,借助z
        print(x , '-->',z)                        #将x最后一个盘中移动到z上
        hanoi(n-1 , y , x , z)                #将前n - 1个盘子从y移动到z上,借助x
>>> hanoi(1,'a','b','c')
a --> c
>>> hanoi(3,'a','b','c')
a --> c
a --> b
c --> b
a --> c
b --> a
b --> c
a --> c

先用大白话翻译下hanoi函数的定义:
def        Hanoi(n,起始柱,暂存柱,目标柱)
        当n=1时:
                1块从 起始柱(a)——>目标柱( c)
        当n>1时:
                第1步:(n-1)块从起始柱(a)——>暂存柱(b)
                第2步:   n块从 起始柱(a)——>目标柱(c)
                第3步:(n-1)块从暂存柱(b)——>目标柱(c)

当执行函数Hanoi(n,a,b,c)时执行到第1步和第3步时又调用了Hanoi(n-1,a,b,c)函数操作
第1步执行:
如果(n-1)=1
        (n-1)块从 起始柱(a)——>目标柱(b)
如果(n-1)>1:
        第1.1步:(n-2)块从起始柱(a)——>暂存柱(c)
        第1.2步:(n-1)块从 起始柱(a)——>目标柱(b)
        第1.3步:(n-2)块从暂存柱(c)——>目标柱(b)
第3步的执行:
如果(n-1)=1
        (n-1)块从 起始柱(b)——>目标柱(c)

如果(n-1)>1:
        第3.1步:(n-2)块从起始柱(b)——>暂存柱(a)
        第3.2步:(n-1)块从 起始柱(b)——>目标柱(c)
        第3.3步:(n-2)块从暂存柱(a)——>目标柱(c)
将问题放上来
else:
        hanoi(n-1 , x , z , y)                #将前n - 1个盘子从x移动到y上,借助z
        #这里为什么是x,z,y的顺序?
        print(x , '-->',z)                        #将x最后一个盘中移动到z上
        hanoi(n-1 , y , x , z)                #将前n - 1个盘子从y移动到z上,借助x
        #这里为什么就又变成是y,x,z的顺序了?
       
        要理解这个首先需要回到之前形参实参知识点。
        起始柱,暂存柱,目标柱————形参
        a,b,c————实参
        在看上面白话翻译hanoi函数时小括号里a,b,c的变化。
       
        如此回到之前的函数中便可以理解:
def hanoi(n,x,y,z): #在定义函数时,这里x,y,z是形参
    if n == 1:
        print(x , '-->' , z)
    else:
        hanoi(n-1 , x , z , y)                #将前n - 1个盘子从x移动到y上,借助z
        # 调用函数时,这里x,z,y是作为实参的,等同于hanoi(n-1 , a , c, b)
        由上述可知在执行第1步后执行第1.1步时,a任是起始柱,而c成为暂存柱,b作为目标柱。(回想位置索引知识点)便很容易理解从c,b为什么要换位置。
        print(x , '-->',z)                        #将x最后一个盘中移动到z上
        hanoi(n-1 , y , x , z)                #将前n - 1个盘子从y移动到z上,借助x
        #同上,所以y,x,z要这样排序

用关键字索引的方式定义hanoi()函数
def hanoi(n,x,y,z):
    if n == 1:
        print(x , '-->' , z)
    else:
        hanoi(n-1 , x=x , y=z , z=y)                #将前n - 1个盘子从x移动到y上,借助z
        print(x , '-->',z)                        #将x最后一个盘中移动到z上
        hanoi(n-1 , x=y , y=x , z=z)                #将前n - 1个盘子从y移动到z上,借助x

总结起来,其实自己困惑纠结的关键点就是位置索引的知识点上
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-7-14 10:44:12 | 显示全部楼层
棒棒啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-8-3 08:06:02 | 显示全部楼层
感谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-9-28 10:00:15 | 显示全部楼层
太棒了!!!!!这样探索的精神值得任何人学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-18 20:10:42 | 显示全部楼层
牛啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-2-16 22:14:27 | 显示全部楼层
与我的想法不谋而合
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-24 15:28

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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