一篇文章带你了解Python递归函数

开发 后端
本文基于Python基础。Python标准的解释器没有针对尾递归做优化,任何递归函数都存在栈溢出。介绍了在使用递归函数的优缺点,优点是逻辑简单清晰,缺点是过深的调用会导致栈溢出。

[[389295]]

一、什么是递归函数?

在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。

二、函数的递归调用原理

实际上递归函数是在栈内存上递归执行的,每次递归执行一次就会耗费一些栈内存。

栈内存的大小是限制递归深度的重要因素

三、案例分析

1.求阶乘

计算阶乘n! = 1 x 2 x 3 x … x n,

可以用函数fact(n)表示。

  1. fact(n) = n! = 1 x 2 x 3 x … x (n-1) x n = (n-1)! x n = fact(n-1) x n 

fact(n)可以表示为n x fact(n-1),只有n=1时需要特殊处理。

于是,fact(n)用递归的方式写出来就是:

  1. def fact(n): 
  2.     if n == 1: 
  3.         return 1 
  4.     return n * fact(n - 1) 

如果计算fact(6),可以根据函数定义看到计算过程如下:

  1. def fac(n): 
  2.     if n==1: 
  3.         return 1 
  4.     else
  5.         res=n*fac(n-1) 
  6.         return  res 
  7.  
  8. print(fac(6)) 

运行结果:

2.斐波拉契级数

有这样一个数列:1,1,2,3,5,8,13,21,34…。其第一元素和第二个元素等于 1,其他元素等于其前面两个元素的和。

例:

  1. def fab(n):  # 定义斐波拉契级数 
  2.     if n in [1, 2]:  # 如果n=1或者2 
  3.       return 1 
  4.     return fab(n - 1) + fab(n - 2)  # n>2 
  5.  
  6.  
  7. print(fab(1))  # 斐波拉契级数的第一个元素 
  8.  
  9. print(fab(2))  # 斐波拉契级数的第二个元素 
  10.  
  11. print(fab(8))  # 斐波拉契级数的第8个元素 
  12. print(fab(13))  # 斐波拉契级数的第9个元素    

运行结果:

3.递归函数的优点

定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。

递归需要注意递归的深度。由于递归会产生多次函数调用,而函数调用会消耗代码的栈空间,如果递归的深度太大,会导致栈溢出。以上面的阶乘为例,如果计算 100000 的阶乘,在一般机器上都会出现栈溢出的问题。

  1. print(fac(10000)) 

如下所示:

四、总结

本文基于Python基础。Python标准的解释器没有针对尾递归做优化,任何递归函数都存在栈溢出。介绍了在使用递归函数的优缺点,优点是逻辑简单清晰,缺点是过深的调用会导致栈溢出。

在实际案例中,针对尾递归优化的语言可以通过尾递归防止栈溢出。尾递归事实上和循环是等价的,没有循环语句的编程语言只能通过尾递归实现循环,进行详细的讲解。

使用Python语言,希望能够帮助你更好的学习。

 

责任编辑:姜华 来源: Go语言进阶学习
相关推荐

2021-04-24 10:19:41

Python函数指向

2021-01-29 18:41:16

JavaScript函数语法

2023-06-15 10:11:08

JavaScript函数表达式

2021-06-30 00:20:12

Hangfire.NET平台

2023-05-12 08:19:12

Netty程序框架

2021-05-21 09:01:29

JavaScript 前端函数闭包

2020-11-10 10:48:10

JavaScript属性对象

2021-02-02 18:39:05

JavaScript

2021-06-04 09:56:01

JavaScript 前端switch

2024-01-30 13:47:45

2023-09-06 14:57:46

JavaScript编程语言

2021-01-26 23:46:32

JavaScript数据结构前端

2021-05-18 08:30:42

JavaScript 前端JavaScript时

2024-04-19 14:23:52

SwitchJavaScript开发

2023-07-30 15:18:54

JavaScript属性

2021-03-09 14:04:01

JavaScriptCookie数据

2021-03-05 18:04:15

JavaScript循环代码

2023-05-08 08:21:15

JavaNIO编程

2021-09-27 09:18:30

ListIterato接口方法

2020-12-08 08:09:49

SVG图标Web
点赞
收藏

51CTO技术栈公众号