鱼C论坛

 找回密码
 立即注册
查看: 2142|回复: 8

[已解决]关于递归

[复制链接]
发表于 2018-9-27 22:37:54 | 显示全部楼层 |阅读模式

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

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

x
def dif2(x):
    if x:
        dif1(x)

def dif1(y):
    if y > 0:
        dif2(y - 3)
        temp = y-3
    print(y)

dif1(21)

输出:
3
6
9
12
15
18
21

烦请大牛解释一下,输出结果,虽然知道递归是利用堆栈实现,但是内部原理感觉还是没有理解很透彻,烦请大牛能讲解细一点吗,谢谢
最佳答案
2018-9-28 15:18:33
Trami 发表于 2018-9-28 10:41
def dif2(x):
    if x:
        dif1(x)

dif1(21)
    if 21 > 0:    # True
        dif2(21 - 3) # x = 18, 18 != 0 ...  >> 等同 dif1(18),好上面的应该没有问题

dif1(3)                                                                      |     def  dif1(y):
    if 3 > 0:    # True                                                  |            if y < 0:  
        dif2(3 - 3) # x == 0,不会执行 dif1(0)                |               dif2(y-3)
    print(3)                                                                 |            print(y)

程序的结构是顺序结构的,也就是从上到下。见 2 楼,原本是先执行 dif1(21)...print(21) 的,但是透过递归,一直在内层安插新的代码
最总的代码会是,这是递归的一个特点,顺序会颠倒

print(3)
print(6)
...
print(21)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-9-27 22:48:39 | 显示全部楼层
一层一层进去,直到遇到结束条件,由内层开始返回

dif1(21)
   dif2(18)
        dif2(15)
             ....   遇到结束,开始由内层返回
        print(15)
    print(18)
print(21)
              
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-27 23:26:18 | 显示全部楼层
大牛,又是你给我讲解了,感谢感谢,我不明白的是,执行下面这句的时候应该只有y=0的时候?
print(y)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-9-27 23:53:38 | 显示全部楼层
Trami 发表于 2018-9-27 23:26
大牛,又是你给我讲解了,感谢感谢,我不明白的是,执行下面这句的时候应该只有y=0的时候?
print(y)

def dif2(x):
    if x:        ## 如果 x 不为零,则执行
        dif1(x)

def dif1(y):
    if y > 0:   ## y <= 0 不执行   21 18 15 12 9 3
        dif2(y - 3)
    print(y)

temp 没有任何作用,重点是为什么不打印 0 ?因为是透过 dif2() 调用 dif1() 的,而 dif2() 的传参是 0 的话将不会执行
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-28 10:41:54 | 显示全部楼层
claws0n 发表于 2018-9-27 23:53
def dif2(x):
    if x:        ## 如果 x 不为零,则执行
        dif1(x)

def dif2(x):
    if x:
        dif1(x)

def dif1(y):
    if y > 0:
        dif2(y - 3)
    print(y)


dif1(21)
    dif2(18)
        dif2(15)
        ...
            dif2(3)
            下一步
            x = y-3 = 0, 此时y=3
            此时dif2()函数将不执行
            我的第一个疑问是:当dif2()函数将不执行, dif1()是否就当if判断语句被跳过, 然后就开始执行print(y) ?
            第二个疑问是:此时y=3, 为什么输出的时候输出的多个数据是倒序? 是因为在做递归输出的时候, 是需要到了停止条件后才开始依次向外输出数据?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-9-28 15:18:33 | 显示全部楼层    本楼为最佳答案   
Trami 发表于 2018-9-28 10:41
def dif2(x):
    if x:
        dif1(x)

dif1(21)
    if 21 > 0:    # True
        dif2(21 - 3) # x = 18, 18 != 0 ...  >> 等同 dif1(18),好上面的应该没有问题

dif1(3)                                                                      |     def  dif1(y):
    if 3 > 0:    # True                                                  |            if y < 0:  
        dif2(3 - 3) # x == 0,不会执行 dif1(0)                |               dif2(y-3)
    print(3)                                                                 |            print(y)

程序的结构是顺序结构的,也就是从上到下。见 2 楼,原本是先执行 dif1(21)...print(21) 的,但是透过递归,一直在内层安插新的代码
最总的代码会是,这是递归的一个特点,顺序会颠倒

print(3)
print(6)
...
print(21)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-28 19:02:51 | 显示全部楼层
claws0n 发表于 2018-9-28 15:18
dif1(21)
    if 21 > 0:    # True
        dif2(21 - 3) # x = 18, 18 != 0 ...  >> 等同 dif1(18), ...

意思就是每次的调用都是在上一层的print前面增加了一个print直到停止,先进入的数据对应最外层的print也就是先入后出,所以递归才说是利用堆栈实现,我这样说应该可以吧?感谢大牛耐心的解答,感谢感谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-9-28 19:41:15 | 显示全部楼层
Trami 发表于 2018-9-28 19:02
意思就是每次的调用都是在上一层的print前面增加了一个print直到停止,先进入的数据对应最外层的print也 ...

对,但是更准确来说,是最后一个函数结束后(弹栈),机器才看到 print(3) 的代码,结束函数,再弹栈,再看到 print(6) ……
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-28 20:19:00 | 显示全部楼层
好的好的,感谢指点,谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-23 17:31

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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