Python函数之六:递归函数

一、什么是函数的递归

1、编程语言中, 函数Func(Type a,…)直接或间接调用函数本身,则该函数称为递归函数。

2、递归的定义:一种计算过程,如果其中每一步都要用到前一步或前几步的结果,称为递归。

3、用递归过程定义的函数, 称为递归函数。

1、调用方式

1.1 直接调用
def func():print('in func')func()
func()

分析:这就是一个直接调用自身的递归函数,因为没有判断边界,是一个死循环函数。

1.2 间接调用
def foo():print('in foo')bar()def bar():print('in bar')foo()
foo()

分析:这是一个间接调用方式的递归函数,foo函数和bar函数相互调用对方形成递归,也是一个死循环。

1.3 总结

1、递推:一层一层递归调用下去,进入下一层递归的问题规模都将会减小;
2、回溯:递归必须要有一个明确的结束条件,在满足该条件开始一层一层回溯;
3、递归的精髓在于通过不断地重复逼近一个最终的结果。

def foo(n):if n == 1:return 1else:return n * foo(n-1)
print(foo(5))#120

分析:
第一次循环:n = 5 返回值:5 * foo(5-1)
第二次循环:n = 4 返回值:5 * 4 * foo(4-1)
第三次循环:n = 3 返回值:5 * 4 * 3 * foo(3-1)
第四次循环:n = 2 返回值:5 * 4 * 3 * 2 foo(2-1)
第五次循环:n = 1 返回值:5 * 4 * 3 * 2 * 1 = 120

二、递归与循环

1、用循环的方式实现阶乘

def foo(n):res = 1for i in range(n):res = res * (i + 1)return res
print(foo(5))#120

2、递归与循环的优缺点

2.1 递归

优点:代码简洁、清晰,并且容易验证正确性。(如果你真的理解了算法的话,否则你更晕)

缺点:
1、它的运行需要较多次数的函数调用,如果调用层数比较深,每次都要创建新的变量,需要增加额外的堆栈处理,会对执行效率有一定影响,占用过多的内存资源。
2、递归算法解题的运行效率较低。在递归调用的过程中系统为每一层的返回点、局部变量等开辟了栈来储存。递归次数过多容易造成栈溢出等。

2.2 循环

优点:速度快,结构简单。

缺点:并不能解决所有的问题。有的问题适合使用递归而不是循环。如果使用循环并不困难的话,最好使用循环

三、递归的应用

1、二分法查找

所谓二分法查找就是在一个区间[a, b]内查找一个数m,判断m是否大于b/2,如果大于,则在[b/2,b]之间查找,如果小于,则在[a,b/2]之间查找,然后重复以上操作来实现的

代码实例:查找列表中[1, 3, 7, 11, 22, 34, 55, 78, 111, 115]的值:78

def foo(n, li):mid_index = int(len(li)/2)print(li)if len(li) == 0:print('not find it')returnif n > li[mid_index]:li = li[mid_index+1:]foo(n, li)elif n < li[mid_index]:li = li[:mid_index]foo(n, li)else:print('find it')li = [1, 3, 7, 11, 22, 34, 55, 78, 111, 115]
foo(78, li)
# [1, 3, 7, 11, 22, 34, 55, 78, 111, 115]
# [55, 78, 111, 115]
# [55, 78]
# find it

2、使用递归打印斐波那契数列(前两个数的和得到第三个数)

#得出斐波那契数列的第n项
def feibo(n):if n <= 1:return nelse:return feibo(n-1) + feibo(n-2)def dayin(n):for i in range(1, n+1):print(f'第{i}项为:{feibo(i)}')
dayin(10)
# 第1项为:1
# 第2项为:1
# 第3项为:2
# 第4项为:3
# 第5项为:5
# 第6项为:8
# 第7项为:13
# 第8项为:21
# 第9项为:34
# 第10项为:55

四、尾递归

1、普通递归

n的阶乘:

def recursion(n):if n == 1:return nelse:return n * recursion(n-1)
print(recursion(5))#120

图解:

分析:
第一次循环:n = 5 返回值:5 * foo(4)
第二次循环:n = 4 返回值:5 * 4 * foo(3)
第三次循环:n = 3 返回值:5 * 4 * 3 * foo(2)
第四次循环:n = 2 返回值:5 * 4 * 3 * 2 * foo(1)
第五次循环:n = 1 返回值:5 * 4 * 3 * 2 * 1

这种普通递归是通过从执行第一个调用开始,都是调用下一个的递归来计算结果,这种方式在中途无法获取结果,只有所有递归都进行完毕才能得到结果。

这种方式虽然也能计算出最终的结果,但是无法操作中途的计算结果,随着递归的深入,之前的一些变量需要分配堆栈来保存。

2、尾递归

n的阶乘:

def tail_recursion(n, total = 1):if n == 1:return totalelse:return tail_recursion(n-1,  total * n)
print(tail_recursion(5))#120

图解:

分析:
第一次循环:n = 5 返回值:tail_recursion(5,1)
第二次循环:n = 4 返回值:tail_recursion(4,5)
第三次循环:n = 3 返回值:tail_recursion(3,20)
第四次循环:n = 2 返回值:tail_recursion(2,30)
第五次循环:n = 1 返回值:tail_recursion(1,120) = 120

尾递归相对传统递归,其是一种特例,实质上尾递归通过添加一个参数用于接收每一次调用后的结果,实现了释放上一次调用函数的栈内存。

在尾递归中,先执行某部分的计算,然后开始调用递归,所以可以得到当前的计算结果,而这个结果也将作为参数传入下一次递归。

这也就是说函数调用出现在调用者函数的尾部,因为是尾部,所以其有一个优越于传统递归之处在于无需去保存任何局部变量,从内存消耗上,实现节约特性。

因为进入最后一步后不再需要参考外层函数(caller)的信息,因此没必要保存外层函数的stack,递归需要用的stack只有目前这层函数的,因此避免了栈溢出风险

Python函数之六:递归函数相关推荐

  1. python 函数递归一次增加一次变量_python3--函数(函数,全局变量和局部变量,递归函数)...

    1.1函数 1.1.1什么是函数 函数就是程序实现模块化的基本单元,一般实现某一功能的集合. 函数名:就相当于是程序代码集合的名称 参数:就是函数运算时需要参与运算的值被称作为参数 函数体:程序的某个 ...

  2. Python面向对象之六:类的约束和super函数

    Python面向对象之六:类的约束和super函数 一.类的约束 类的约束就是对父类对子类的属性和方法进行一定的约束控制. 1.对子类属性的约束(slots) class A:__slots__ = ...

  3. python 函数递归一次增加一次变量_python3 --函数(函数,全局变量和局部变量,递归函数’)...

    1.1函数 1.1.1什么是函数 函数就是程序实现模块化的基本单元,一般实现某一功能的集合. 函数名:就相当于是程序代码集合的名称 参数:就是函数运算时需要参与运算的值被称作为参数 函数体:程序的某个 ...

  4. 好好学python·函数进阶(递归函数,回调函数,闭包函数,匿名函数,迭代器)

    函数进阶 递归函数 回调函数 闭包函数 特点 匿名函数 lambda 表达式 迭代器 iter() next() 迭代器的取值方案 迭代器取值特点,取一个少一个,直到都取完,最后再获取就会报错 检测迭 ...

  5. python递归函数1到n的平方和_python中的高阶函数与递归函数

    高阶函数 一个函数作为另一个函数的参数传入:函数名可以作为返回值:这样的函数即为高阶函数. 例如:求两个数的平方和 def f(m): return m*m def f1(a,b,function): ...

  6. Python 2.4 递归函数

    递归函数 在函数内部,可以调用其他函数.如果一个函数在内部调用本身,这个函数就是递归函数. 举个例子:计算阶乘n!=1*2*3*4*5*...*n,用函数fact(n)表示,可以看出 fact(n)= ...

  7. Python进阶之递归函数的用法及其示例

    作者 | 程序员adny 责编 | 徐威龙 封图| CSDN│下载于视觉中国 出品 |  AI科技大本营(ID:rgznai100) 本篇文章主要介绍了Python进阶之递归函数的用法及其示例,现在分 ...

  8. python函数(三)

    一.函数定义 定义:def语句,依次写出函数名.括号.括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回. 例如: def my_abs(x): ifx >=0 ...

  9. 【Python基础】Python 函数使用总结

    我的施工之路 目前已完成,以下五期Python专题总结: 1我的施工计划 2数字专题 3字符串专题 4列表专题 5流程控制专题 6编程风格专题 今天是Python函数专题,目录结构: Python 函 ...

最新文章

  1. shiro 没有注销再登录_Shiro 详细介绍 068
  2. oracle方差和协方差函数,[转载]方差var、协方差cov、协方差矩阵(浅谈)(三)_函数cov...
  3. PDA端的数据库一般采用的是sqlce数据库
  4. 11.MYSQL高级(一)
  5. 浙大 PAT b1040
  6. 图像的放大与缩小——双线性插值放大与均值缩小
  7. Spark On Hive配置
  8. 客户端配置ARP绑定防止ARP网关欺骗
  9. 实用好用的在线二维码生成器有哪些?
  10. 油猴/暴力猴工具换cook脚本
  11. C4D插件X-Particles粒子特效(八)
  12. 信息系统项目管理师 - 项目组合管理
  13. 如何解决word添加脚注后正文跑到下一页的问题
  14. 独门秘籍 针式打印机换针小窍门
  15. 2020ICPC昆明热身赛 C.Statues(前缀优化dp+滚动数组优化空间)
  16. 服务器数据恢复;IBM V7000数据恢复方法
  17. HihoCoder - 1370 快乐数字
  18. iphoneipad图标尺寸
  19. 网站提示DNS_PROBE_FINISHED_NXDOMAIN错误如何修复
  20. idea加密解密C++实现

热门文章

  1. 四路红外避障模块使用
  2. 怎么区分C和C++?
  3. 如何制作普通光盘刻录360分钟的VCD影片
  4. 平台币蓄势待发,值得投资的有哪些?
  5. 输出大写英文字母PTA
  6. 直流电源滤波电容选择
  7. 电脑进水后自救技巧以及被删除的文件如何恢复方法分享
  8. TeeChart用法
  9. 主成分分析法(数学建模)教授先生
  10. 通关这8个游戏,保证你能精通CSS