Python递归思想与代码实现
1, 递归思想
递归算法:递归(Recursion),在数学与计算机科学中,是指在函数的定义中使用函数自身的方法。
这是官方的解释,翻译成人话就是:
- 函数内部自己调用自己
- 函数必须有出口
函数自己调用自己很好理解,但什么是出口呢?我们知道,递归实际上是简化嵌套for循环的一种精简算法,所以在函数内部自己调用自己的过程就是在不短的循环,并改变函数传入的参数。如果没有不再执行自己调用自己的出口,那么递归就会陷入无限循环的无底洞。
出口通常是用return或if else语句避免再调用自己。
def recursion(n):print(n, "<===1====>")if n > 0:recursion(n - 1)# 那么这就是一个出口,如果n <= 0了就会不再递归else:print(n, '<===2====>')recursion(5) # 外部调用
结果就是:
5 <===1====>
4 <===1====>
3 <===1====>
2 <===1====>
1 <===1====>
0 <===1====>
0 <===2====> # 这个是出口,在这个时候n = 0Process finished with exit code 0
递归还有两个重要的思想,第一个我们要找到等价的运算式,也就是将大问题拆分成很多个可递归的小问题。
第二个:
- 递推:像上边递归实现所拆解,递归每一次都是基于上一次进行下一次的执行,这叫递推。
- 回溯:则是在遇到终止条件,则从最后往回返一级一级的把值返回来,这叫回溯。
听到这是不是有点懵,我们来通过下面阶乘的实例与代码实现来进一步理解这个思想。
2,递归求阶乘,代码实现与思想解析
首先先上代码:
def factorial(n):# 出口if n == 1:return 1else:return n * factorial(n-1)print(factorial(5))
这段代码求出了5的阶乘,大家先试着理解。
其中出口就是在n - 1 = 1的时候,递归就开始了回溯。
我们看一下流程图:
n * factorial(n-1)是等价表达式。红色箭头是递推的过程,从1-2-3-4;绿色箭头是回溯的过程,从a-b-c-d;紫色箭头是参数的变化。我把每一个式子都分解了一下,我们可以发现最后真正输出的是最外层的return,回溯顺序是从最底层往上返回。
如果我们改一下代码,在每一次回溯的时候输出等价表达式的值:
def factorial(n):# 出口if n == 1:return 1# 递归内层else:factor = n * factorial(n-1)print(factor)return factorprint(factorial(5))
输出:
2
6
24
120
120Process finished with exit code 0
不难发现,第一个输出的2就是流程图中的a式的值,6是b式的值,24是c式的值,120就是d式也就是最外层返回的5的阶乘了。
通过此输出,也证明了回溯过程的实现。这样我们就可以利用此思想求斐波那契数列等等等。那么递归其实也是可以用for来实现的。
# 求5的阶乘
num = 1
for i in range(1,6):num *= i
print(num)
3,栈溢出
递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出),此时程序会抛出错误:超出最大递归深度。
那么一般最大的深度是1000左右,我们可以通过sys的两个方法来设置最大深度和得到最大深度。
import sys# 得到最大的深度值
print(sys.getrecursionlimit())
# 设置最大深度为2000
sys.setrecursionlimit(2000)
4,运行速度
import sys
import time
print(sys.getrecursionlimit())
sys.setrecursionlimit(2000)
start = time.time()def factorial(n):# 出口if n == 1:return 1# 递归内层else:return n * factorial(n-1)print(factorial(1000))
print(time.time() - start)
我们通过time方法来获取运行的时间,发现大概在0.008s左右
而for循环实测在0.004秒左右,所以我们看到递归的缺点是资源占用和运行速度劣与for循环。
所以我们总结一下递归的缺点:
- 递归由于是函数调用自身,而函数调用是有时间和空间的消耗的--效率
- 递归中很多计算都是重复的,由于其本质是把一个问题分解成两个或者多个小问题,多个小问题存在相互重叠的部分,则存在重复计算--效率
- 调用栈可能会溢出,其实每一次函数调用会在内存栈中分配空间,而每个进程的栈的容量是有限的,当调用的层次太多时,就会超出栈的容量,从而导致栈溢出,强制设置最大深度会导致内存占用大--性能
优点:
- 简洁
- 在特殊情况下比for循环更加简洁,逻辑清晰。
4,建议
在使用for循环运算量并不太大时使用递归,在for循环逻辑太过于繁琐时使用递归。
Python递归思想与代码实现相关推荐
- Python 二分查找(涉及递归思想)
二分查找介绍 二分查找(搜索)是一种在有序列表中查找某一特定元素的搜索算法. 首先先查找到目标列表的中间元素,如果中间元素正好是要查找的元素,则返回查找元素的索引下标,搜索结束:如果要查找的元 ...
- Python中的匿名函数及递归思想简析
匿名函数 前言 很多人学习python,不知道从何学起. 很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手. 很多已经做案例的人,却不知道如何去学习更加高深的知识. 那么针对这三类 ...
- Python中匿名函数及递归思想简析(小本本记下来)
前言: 上次咱们基本说了一下函数的定义及简单使用,想要了解的伙伴可以去看看.Python中最基本的函数及其常用用法简析(新手必备)小本本记起来 现在咱们整点进阶一些的.同样都是小白,咱也不知道实际需要 ...
- python匿名函数的作用_Python中的匿名函数及递归思想简析
匿名函数 前言 上次咱们基本说了一下函数的定义及简单使用,Python中的基本函数及其常用用法简析,现在咱们整点进阶一些的.同样都是小白,咱也不知道实际需要不,但是对于函数的执行顺序以及装饰器的理解还 ...
- Javascript函数之深入浅出递归思想,附案例与代码!
作者 | 浮世万千吾爱有三 责编 | Carol 来源 | CSDN 博客 递归函数的理解 1.生活中的递归 "递归"在生活中的一个典例就是"问路".如图小哥哥 ...
- python递归实例_python实现递归实例代码
# 递归:在某个函数内部自己调用了自己# 递归和循环一样,必须要有退出条件.如果没有退出条件,就会无限调用自身,相当于死循环. 工具/原料 python3.6 pycharm 方法/步骤 1 def ...
- 十大排序算法思想和代码总结(Python版)
Table of Contents 一.概述 二.算法简介及代码展示 1.冒泡排序($O(n^2)$) 2.简单选择排序($O(n^2)$) 3.简单插入排序($O(n^2)$) 4.堆排序($O(n ...
- Python递归实现快速排序
原文:http://blog.csdn.net/zhoufen12345/article/details/53560172 快速排序(QuickSort)是对冒泡排序的一种改进: 基本思想: 通过一趟 ...
- 匿名函数自我调用_Python中的匿名函数及递归思想简析
匿名函数 前言 上次咱们基本说了一下函数的定义及简单使用,Python中的基本函数及其常用用法简析,现在咱们整点进阶一些的.同样都是小白,咱也不知道实际需要不,但是对于函数的执行顺序以及装饰器的理解还 ...
最新文章
- 学生管理系统(C语言版)
- css实现左侧宽度自适应,右侧固定宽度
- Kafka Architecture
- oracle数据库迁移方案二
- Class-dump
- C#枚举数值与名称的转换
- Java基础- super 和 this 解析
- leetcode之回溯backtracing专题2
- dict( )、zip( )函数——python小练
- 大学论文的研究框架是什么?
- 必看!!PMP考试答题技巧
- 如何在移动硬盘上安装Ubuntu系统(1)
- matlab生成word文档
- 全球制造业“看上去很美”
- 鸿蒙之初彩蛋攻略,鸿蒙圣女 热血精灵派鸿蒙灵帝解析
- typora配置好smms后还是typora上传图片失败:image load failed。
- 浏览器是先执行js还是先加载HTML,在HTML中使用JavaScript(浏览器对js的加载机制分析)...
- C语言实现 IFFT 运算
- 经典题:用Java打印空心菱形
- 安装CUDA-10.0
热门文章
- c语言小孩分苹果问题答案忘了,大师网-小朋友学C语言(13):分苹果(小学奥数题)...
- 装修客户有哪些渠道可以找:装修客户资源在哪里找:装修行业怎么找客户?
- java redis缓存使用_redis缓存在项目中的使用
- Java Agent如何在IDEA里调试
- 传送门骑士无限物品的服务器,传送门骑士怎么无限刷资源 无限资源获得方法...
- 超简单超实用MySQL修改密码方法来喽
- Android dialog 弹窗背景图片默认为白色问题
- 华为无线路由器中继模式设置
- 通过IPV6公网远程访问路由(Padavan)
- 「第12章 低风险发布」