Trami 发表于 2018-9-27 22:37:54

关于递归

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

烦请大牛解释一下,输出结果,虽然知道递归是利用堆栈实现,但是内部原理感觉还是没有理解很透彻,烦请大牛能讲解细一点吗,谢谢

claws0n 发表于 2018-9-27 22:48:39

一层一层进去,直到遇到结束条件,由内层开始返回

dif1(21)
   dif2(18)
      dif2(15)
             ....   遇到结束,开始由内层返回
      print(15)
    print(18)
print(21)
            

Trami 发表于 2018-9-27 23:26:18

大牛,又是你给我讲解了,感谢感谢,我不明白的是,执行下面这句的时候应该只有y=0的时候?
print(y)

claws0n 发表于 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 的话将不会执行

Trami 发表于 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, 为什么输出的时候输出的多个数据是倒序? 是因为在做递归输出的时候, 是需要到了停止条件后才开始依次向外输出数据?

claws0n 发表于 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)                                                                      |   defdif1(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)

Trami 发表于 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也就是先入后出,所以递归才说是利用堆栈实现,我这样说应该可以吧?感谢大牛耐心的解答,感谢感谢

claws0n 发表于 2018-9-28 19:41:15

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

对,但是更准确来说,是最后一个函数结束后(弹栈),机器才看到 print(3) 的代码,结束函数,再弹栈,再看到 print(6) ……

Trami 发表于 2018-9-28 20:19:00

好的好的,感谢指点,谢谢
页: [1]
查看完整版本: 关于递归