• day13-Python运维开发基础(递归与尾递归)


    递归与尾递归

    # ### 递归函数
    """
    递归函数: 自己调用自己的函数
    递:去
    归:回
    有去有回是递归
    """
    
    # 简单递归
    def digui(n):
        print(n,"<===1===>")
        if n > 0:
            digui(n-1)
        print(n,"<===2===>")
    digui(5)
    """
    # 代码解析:
    去的过程
    n = 5 print(5,"<===1===>") 5>0 满足 digui(n-1) -> digui(5-1) -> digui(4) 代码在13行,暂定阻塞
    n = 4 print(4,"<===1===>") 4>0 满足 digui(n-1) -> digui(4-1) -> digui(3) 代码在13行,暂定阻塞
    n = 3 print(3,"<===1===>") 3>0 满足 digui(n-1) -> digui(3-1) -> digui(2) 代码在13行,暂定阻塞
    n = 2 print(2,"<===1===>") 2>0 满足 digui(n-1) -> digui(2-1) -> digui(1) 代码在13行,暂定阻塞
    n = 1 print(1,"<===1===>") 1>0 满足 digui(n-1) -> digui(1-1) -> digui(0) 代码在13行,暂定阻塞
    n = 0 print(0,"<===1===>") 0>0 不满足  print(0,"<===2===>")
    
    回的过程
    n = 1 从上一次13行的位置,往下执行, print(1,"<===2===>")
    n = 2 从上一次13行的位置,往下执行, print(2,"<===2===>")
    n = 3 从上一次13行的位置,往下执行, print(3,"<===2===>")
    n = 4 从上一次13行的位置,往下执行, print(4,"<===2===>")
    n = 5 从上一次13行的位置,往下执行, print(5,"<===2===>")
    """
    
    """
    每调用一次函数就会开辟栈帧空间
    n = 5
        n = 4
            n = 3
                n = 2
                    n = 1
                        n = 0
                    n = 1
                n = 2
            n = 3
        n = 4
    n = 5
    """
    
    """
    # 总结:
    递归函数特点1:
        有去有回是递归,去的过程是不断的开辟栈帧空间,回的过程是不断的释放栈帧空间,递归函数就是不断的开辟和释放栈帧空间的过程
    递归函数特点2:
        递归函数触发回的过程一共有2点:(1) 当最后一层空间所有代码执行结束的时候 (2)当函数遇到return的时候 会触发回的过程,回到上一层空间调用处
    递归函数特点3:
        必须给与递归函数一个跳出的条件,不能无限次的递归下去,会造成内存溢出报错,如果递归的层数过多,不推荐使用
    递归函数特点4:
        每次调用函数,开辟的栈帧空间,都是一个独立的个体,里面的变量,名字虽然一样,但是彼此不共享,独立的一份;
    """
    
    # 默认递归深度是1000层 , 当前电脑是995层 
    """
    def deep():    
        deep()
    
    deep()
    """
    递归 示例代码
    # 求5的阶乘 5! = 5*4*3*2*1
    
    n = 5
    total = 1
    for i in range(5,0,-1):
        total *= i
        # total = total * i => 1 * 5
        # total = total * i => 1 * 5 * 4
        # total = total * i => 1 * 5 * 4 * 3
        # total = total * i => 1 * 5 * 4 * 3 * 2
        # total = total * i => 1 * 5 * 4 * 3 * 2 * 1
    print(total)
    
    def jiecheng(n):
        if n <= 1:
            return 1
        return n * jiecheng(n-1)
    
    res = jiecheng(5)
    print(res)
    """
    # 代码解析:
    去的过程
    n = 5 return n * jiecheng(n-1) => 5 * jiecheng(4)
    n = 4 return n * jiecheng(n-1) => 4 * jiecheng(3)
    n = 3 return n * jiecheng(n-1) => 3 * jiecheng(2)
    n = 2 return n * jiecheng(n-1) => 2 * jiecheng(1)
    n = 1 return 1
    
    回的过程
    n = 2 return n * jiecheng(n-1) => 2 * 1
    n = 3 return n * jiecheng(n-1) => 3 * 2 * 1
    n = 4 return n * jiecheng(n-1) => 4 * 3 * 2 * 1
    n = 5 return n * jiecheng(n-1) => 5 * 4 * 3 * 2 * 1
    return 120
    """
    
    # 尾递归: 自己调用自己,且非表达式 [在参数中进行运算]
    """
    可以简化逻辑:只需要考虑去的过程,不需要考虑回的过程,减少逻辑(推荐)
    去的过程,最后一层空间的返回值,就是回的过程,最上层空间所能够接受到的值
    
    理论上,尾递归只开辟一个栈帧空间,但cpython解释器不支持,大型的服务厂商有自己独立的解释器可以支持;
    """
    def jiecheng(n,endval):
        if n <= 1:
            return endval
        return jiecheng(n-1,n*endval)
    res = jiecheng(5,1)
    print(res)
    
    """
    # 代码解析:
    去的过程
    n=5,endval=1   return jiecheng(n-1,n*endval) => jiecheng(5-1,5*1) => jiecheng(4,5*1)
    n=4,endval=5*1 return jiecheng(n-1,n*endval) => jiecheng(4-1,5*1*4) => jiecheng(3,5*1*4)
    n=3,endval=5*1*4 return jiecheng(n-1,n*endval) => jiecheng(3-1,5*1*4*3) => jiecheng(2,5*1*4*3)
    n=2,endval=5*1*4*3 return jiecheng(n-1,n*endval) => jiecheng(2-1,5*1*4*3*2) => jiecheng(1,5*1*4*3*2)
    n=1,n <= 1 , return endval
    
    回的过程
    n=2 return 5*1*4*3*2
    n=3 return 5*1*4*3*2
    n=4 return 5*1*4*3*2
    n=5 return 5*1*4*3*2
    """
    
    # 斐波那契数列: 1,1,2,3,5,8,13,21,34,55 ,.... 第n个数字是几?
    def feib(n):
        if n == 1 or n == 2:
            return 1
        return feib(n-1)+feib(n-2)
    res = feib(5)
    print(res)
    
    """
    # 代码解析:
    n = 5
    return feib(4) + feib(3)
                   feib(4) [=>3]           +              feib(3) [2]
            feib(3)   +   feib(2)                    feib(2) + feib(1)
      feib(2) + feib(1) +  1                            1    +  1
         1    +   1
    """
    尾递归_斐波那契数列 示例代码

    day13

  • 相关阅读:
    微软警告:“大规模电子邮件活动”正在推动勒索软件感染
    静态莫队分块
    可持久化线段树练习题
    KMP的一些好题
    KMP模式匹配
    最大异或路径
    人类分块精华(Ex)
    人类分块精华(二)
    人类分块精华(一)
    Treap 详解
  • 原文地址:https://www.cnblogs.com/reachos/p/12147199.html
Copyright © 2020-2023  润新知