zoukankan      html  css  js  c++  java
  • Python中的递归函数

    递归函数recursion

    函数直接或者间接调用自身,这就是递归函数。能用递归函数解决的问题,一般使用循环也可以解决。递归函数一定要有边界

    递归函数的案例

    一、斐波那契数列

    求斐波那契数列前n项

    def fib(n):
        return 1 if n < 1 else fib(n - 1) + fib(n - 2)
    
    
    for i in range(5):
        print(fib(i), end=' ')

    循环的写法

    def fib(n):
        pre = 0
        cur = 1
        for i in range(n):
            pre, cur = cur, pre + cur
            print(cur, end=' ')
    
    
    fib(5)

    二、阶乘

    def fn(n):
        if n==1:
            return 1
        return n * fn(n-1)
    
    print(fn(5))

    循环的写法

    def fn(n):
        result = n
        for i in range(1, n):
            result *= i
        return result
    
    print(fn(5))

    三、幂

    def p(x, y):
        if y == 0:
            return 1
        return x * p(x, y - 1)
    
    
    print(p(3, 3))

    循环的写法

    def p(x, y):
        result = 1
        for _ in range(y):
            result *= x
        print(result)
    
    
    p(3, 3)

    四、二分查找

    def search(seq, num, lower, upper):
        if lower == upper:
            assert num == seq[upper]
            return upper
        else:
            middle = (lower + upper) // 2
            if num > seq[middle]:
                return search(seq, num, middle + 1, upper)
            else:
                return search(seq, num, lower, middle)
    
    # lst = [0,0,0,0,0,0]
    lst = [4, 25, 8, 23, 4, 100, 95]
    lst.sort()
    print(lst)
    print(search(lst, 0,0,0))

    如果lower下限和upper上限相同,那么久可以断言这就是要查找数字所在的位置,直接返回即可。否则,先找出中间位置,再确定是在左半部分还是在右半部分,适用递归调用函数即可。

    可以将代码的上限和下限参数给出默认值,这样就使代码更灵活

    def search(seq, num, lower=0, upper=None):
        if upper is None:
            upper = len(seq) - 1
        if lower == upper:
            assert num == seq[upper]
            return upper
        else:
            middle = (lower + upper) // 2
            if num > seq[middle]:
                return search(seq, num, middle + 1, upper)
            return search(seq, num, lower, middle)
    
    
    lst = [34, 67, 8, 123, 4, 100, 95]
    lst.sort()
    print(lst)
    print(search(lst, 34))

    递归函数的深度问题

    Python对递归函数的深度做了限制,默认最大1000次,可以使用sys.getrecursionlimit()查询,使用sys.setrecursionlimit()进行修改

    import sys
    print(sys.getrecursionlimit())

    结果

    1000

    如果超出了递归深度的限制,将跑出异常RecursionError: maximum recursion depth exceeded

    def fn():
        return fn()
    fn()

    异常

      File "C:/Users/ASUS-PC/PycharmProjects/函数.py", line 98, in fn
        return fn()
    RecursionError: maximum recursion depth exceeded

    递归函数的性能

    递归和循环的性能对比

    递归的测试

    import datetime
    
    start = datetime.datetime.now()
    n=25
    
    def fib(n):
        return 1 if n < 2 else fib(n - 1) + fib(n - 2)
    
    for i in range(n):
        print(fib(n), end=' ')
    
    delta = (datetime.datetime.now() - start).total_seconds()
    
    print(delta)

    运行结果

    0.751987

    循环的测试

    import datetime
    
    start = datetime.datetime.now()
    pre = 1
    cur = 1
    for i in range(10000):
        pre, cur = cur, pre + cur
        print(cur,end=' ')
    delta = (datetime.datetime.now() - start).total_seconds()
    
    print(delta)

    运行结果

    0.048139  

    对于斐波那契数列的改进

    def fib(n, pre=1, cur=1):
        pre, cur = cur, pre + cur
        print(cur, end=' ')
        if n == 2:
            return
        fib(n - 1, pre, cur)
    
    
    fib(300)

    间接递归

    通过其他函数调用自身,应该从代码规范上规避这种情况

    def fn():
        fn1()
    
    def fn1():
        fn()
    
    fn()
  • 相关阅读:
    设计模式之美学习-接口隔离原则(七)
    设计模式之美学习-里式替换原则(六)
    设计模式之美学习-开闭原则(五)
    设计模式之美学习-设计原则之单一职责(四)
    设计模式之美学习-如何进行面向对象设计(三)
    ffmpeg 从内存中读取数据(或将数据输出到内存)
    CImage 对话框初始化时候显示透明 PNG
    RTMPdump(libRTMP) 源代码分析 9: 接收消息(Message)(接收视音频数据)
    RTMPdump(libRTMP) 源代码分析 8: 发送消息(Message)
    RTMPdump(libRTMP) 源代码分析 7: 建立一个流媒体连接 (NetStream部分 2)
  • 原文地址:https://www.cnblogs.com/zh-dream/p/13906309.html
Copyright © 2011-2022 走看看