• 函数7:递归


    目录

    1. 递归基础

    2. 递归效率

    3. 递归实操

    3.1 实例1:计算阶乘

    3.2 实例2:斐波那契数列

    3.3. 实例3:汉诺塔


    1. 递归基础

    所谓递归(recursion),就是函数调用自身的过程;

    使用递归必须要有判断和结束条件,并且每次调用都要向着这个结束条件去推进,否则递归过程将永远执行下去直至耗尽所有内存资源;

    Python3为防止出现上述永远执行下去的问题,对递归深度做了默认限制,也可以通过 Ctrl + C 让Python强制终止。

    示例如下:

    1. def funx(var):
    2. if var >= 0:
    3. print(f'当前输入参数={var}')
    4. var -= 1
    5. funx(var)
    6. funx(5)
    7. 当前输入参数=5
    8. 当前输入参数=4
    9. 当前输入参数=3
    10. 当前输入参数=2
    11. 当前输入参数=1
    12. 当前输入参数=0

    2. 递归效率

    递归需要从最底层函数一层层返回,当递归层数较大时,效率很低。

    如下示例中对比了迭代和递归两种算法的代码量与执行效率,结果可见递归在数据量较大时效率很低;因此,通常推荐:数据量小时用递归,数据量大时用迭代。

    1. def fiboIter(var):
    2. if var == 1:
    3. result = [1]
    4. elif var > 1:
    5. result = [1, 1]
    6. for i in range(2,var):
    7. result.append(result[i-2]+result[i-1])
    8. return result
    9. def fiboIter2(var):
    10. if var == 1:
    11. return [1]
    12. elif var == 2:
    13. result = fiboIter2(var-1)
    14. result.append(1)
    15. return result
    16. elif var > 2:
    17. result = fiboIter2(var-1)
    18. result.append(result[var-3] + result[var-2])
    19. return result
    20. import timeit
    21. #单轮500级数列耗时
    22. starttime = timeit.default_timer()
    23. print("The start time is :",starttime)
    24. fiboIter(500)
    25. print("The time difference is :", timeit.default_timer() - starttime)
    26. starttime = timeit.default_timer()
    27. print("The start time is :",starttime)
    28. fiboIter2(500)
    29. print("The time difference is :", timeit.default_timer() - starttime)
    30. #100轮100级数列耗时
    31. print('迭代做斐波那契100级数列数列100次生成耗时:',timeit.timeit('fiboIter(100)', setup='from __main__ import fiboIter', number=100))
    32. print('迭代做斐波那契100级数列数列100次生成耗时:',timeit.timeit('fiboIter2(100)', setup='from __main__ import fiboIter2', number=100))
    33. The start time is : 1.0402109
    34. The time difference is : 8.000000000008001e-05
    35. The start time is : 1.0402999
    36. The time difference is : 0.0003684000000001575
    37. 迭代做斐波那契100级数列数列100次生成耗时: 0.0010354000000000196
    38. 迭代做斐波那契100级数列数列100次生成耗时: 0.0021157000000000536

    3. 递归实操

    3.1 实例1:计算阶乘

    阶乘:

    一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且0的阶乘为1。自然数n的阶乘写作n!。

    即n!=1×2×3×...×(n-1)×n。阶乘亦可以递归方式定义:0!=1,n!=(n-1)!×n。

    亦即n!=1×2×3×...×(n-1)×n。阶乘亦可以递归方式定义:0!=1,n!=(n-1)!×n。

    迭代实现:

    1. def factorial(var:int) -> int:
    2. result = 1
    3. for i in range(1,var+1):
    4. result *= i
    5. return result
    6. factorial(10)
    7. 3628800

    递归实现:

    1. def factorial(var:int) -> int:
    2. if var == 0:
    3. return 1
    4. elif var > 0:
    5. return var * factorial(var-1)
    6. factorial(10)
    7. 3628800

    3.2 实例2:斐波那契数列

    斐波那契数列(Fibonacci sequence):

    又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)

    迭代实现:

    1. def fiboIter(var):
    2. if var == 1:
    3. result = [1]
    4. elif var > 1:
    5. result = [1, 1]
    6. for i in range(2,var):
    7. result.append(result[i-2]+result[i-1])
    8. return result
    9. fiboIter(10)
    10. [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

    递归实现:

    1. def fiboIter2(var):
    2. if var == 1:
    3. return [1]
    4. elif var == 2:
    5. result = fiboIter2(var - 1)
    6. result.append(1)
    7. return result
    8. elif var > 2:
    9. result = fiboIter2(var - 1)
    10. result.append(result[var - 3] + result[var - 2])
    11. return result
    12. fiboIter2(10)
    13. [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

    3.3. 实例3:汉诺塔

    汉诺塔规则说明:

    递归实现:

    1. def hannuota(layer:int,post1:str,post2:str,post3:str):
    2. if layer == 1:
    3. print(f'第{layer}片: {post1} => {post3}')
    4. elif layer > 1:
    5. hannuota(layer-1,post1,post3,post2)
    6. print(f'第{layer}片: {post1} => {post3}')
    7. hannuota(layer-1,post2,post1,post3)
    8. print('3片汉诺塔:')
    9. hannuota(3,'甲','乙','丙')
    10. print('------------------终止------------------')
    11. 3片汉诺塔:
    12. 1片: 甲 => 丙
    13. 2片: 甲 => 乙
    14. 1片: 丙 => 乙
    15. 3片: 甲 => 丙
    16. 1片: 乙 => 甲
    17. 2片: 乙 => 丙
    18. 1片: 甲 => 丙
    19. ------------------终止------------------

  • 相关阅读:
    如何压缩视频?视频压缩变小方法汇总
    什么是高企认定?高企认定的8个条件!
    学会Spring Cloud微服务架构绝活,渣本也能进大厂
    实战Kaggle比赛:预测房价
    Zetora初始化使用方法
    JavaEE——Java线程的几种状态
    计算机java项目|springboot校园一卡通
    微信小程序之接口预加载
    每天学一个MySQL函数(一):CONCAT
    ChatGPT类大模型应用入门了解与使用
  • 原文地址:https://blog.csdn.net/davidksatan/article/details/125402708