轻松搞懂Python递归函数的原理与应用

article/2025/10/25 3:56:40

递归: 在函数的定义中,函数内部的语句调用函数本身。

1、递归的原理

学习任何计算机语言过程中,“递归”一直是所有人心中的疼。不知你是否听过这个冷笑话:“一个面包,走着走着饿了,于是就把自己吃了”。

常理推断,特别是解释型语言,当程序执行函数内部的语句时,这个函数还没有定义完,没定义完怎么可以调用本身呢。

但实质上,当你执行函数内部的语句时,一定有函数外部的语句调用了这个函数,此时该函数的所有代码和语句,已经在内存中形成了逻辑,这就是递归函数的原理。

在Python当中很重要的就是递归的使用。

2、递归的玩法

牛叔语录:人类创造出的任何复杂的概念,都是为了让事情变得更简单一些。

递归是为了更好的解决,“自已定义自己”的数学或是哲学难题。

用好递归,有2个、2个、2个(重要的事情说3遍)要点,必须要同时注意,下面请各位评委看我的表演。

(1) 认清自己

认清自己是递归玩法的核心。与处理任何事情一样,首先要问的就是:如何准确地定义好“当前要做的事情”。处理好这个问题,我们就已经成功了一半。

此处我们拿数学函数为例, 因为数学函数的定义有公式,显而易见,它的意义就是根据变量来计算出结果,最容易被小白理解,栗子如下:

假设数学函数:

 f(n) = (f(n-1) + 1)*2 ,告诉你f(1)=1,问f(10)是多少?

我们直接把这个f(n)定义成函数,并且计算f(10) 如下:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def f(n):if n==1:return 1else:return (f(n-1)+1)*2print(f(10))

结果是1534,运行正确。恭喜你这是一道著名的数学难题,你竟然轻松解决了,原题这样:

猴子有一堆桃子,每天吃前一天剩下的一半多1个,昨天吃完发现剩了1个,那么前10天它剩下多少个桃子?

我们公式中的n就表示前n天,公式结果就表示剩下了多少桃子,昨天的桃子y总比今天的x有这样的关系:x = y/2 -1所以:y=(x+1)*2,这个就是上面的公式。

在写本递归函数时,语句基本上照抄数学公式,我们不知道解题过程就能求出答案,真是太神奇了!只要定义好,递归跑不了!慢着,别下结论,我们再看看如下的点。

(2)把握好方向

与上面的“猴子摘桃”同一个问题,原题我们改一下说法,问:

猴子第1天摘了一堆桃子吃了一半又多一个,第2天吃了剩下的一半又多一个,…,第10天早上时发现只有1个桃子了。问第1天摘了多少?这回我们把n设为第n天(而不是前n天)

与上面函数f类似,后项也是根据前项值来确定,为区别我们使用g()代表该函数:

 g(n) = g(n-1)/2 -1 ,告诉你 g(10)=1,问g(1) 是多少?

牛叔说了,“只要定义好,递归跑不了”,我们先不管三七二十一,照抄上面的数学公式,“迅速而又准确”地把g(n)函数用如下的代码造了出来,如下:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def g(n):if n==10:return 1else:return g(n-1)/2 - 1print(g(1))

运行后却出现了如下的错误,提示递归溢出!

在这里插入图片描述
这是怎么回事呢?因为我们还有第2个点,您没有注意!

这个点就是 “要想递归不出错,开车方向不能错”,这个方向是指: 程序求解的方向必须和定义的方向相同,

此处我们要根据n=10的结果来求n=1,方向是:后项(10)->前项(1),而程序中翻译的公式是 前项(n-1)->后项(n),根据公式写的程序,也只能完成公式的求解顺序,即:n从小到大的推导,

所以此时如果求g(100),结果是这样的,完全没有问题(但没有任何意义):

-2.0

所以此处要通过我们的智慧把这个公式,“颠倒”过来变成:

 g(n-1) = (g(n)+1) * 2    => g(n) = (g(n+1)+1) * 2 

这样根据公式写的代码,就可以完成从后项(n+1)推导到前项(n)的功能了!

如果不理解,小学二年级的代数再看一遍,具体程序如下:

def g(n):if n==10:return 1else:return 2*(g(n+1)+1)print(g(1))

终于得出了正确的结果,1534。答案和第1题一样!猴子终于满意了,10天的口粮有着落了。

3、分解质因数练习

小学生专用名词,别给吓住了,其实就是把数字分解成不能再分解的乘法,比如:8=2*2*2, 10 = 2*5,而不是 8 = 2 * 4这种可以再分解的。

此递归问题,是编程竞赛常客,拿来练手比较合适。如下Python代码,对于本问题的解答充分说明了递归的方便之处,以分解了980这个整数为示例:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def defactor(N):  #定义一个函数名称为defactor,意义是返回N的所有因子for i in range(2,N): #从2开始试试if N%i ==0: #如果试到i是N的因子的话,就返回i的所有因子和N/i的所有因子 的列表return defactor(i)+defactor(int(N/i))else:#如果没有试到就说明这个N是一个质数,就直接包含它的 列表return [N]print(defactor(980))

运行的答案是:

[2, 2, 5, 7, 7]

Bingo,在这里函数defactor(N)

(1)定义: 求出参数N所有因子的数组,

(2)方向:整数 -> 最小的质数

首先,理解else:部分(代码中的第5,6两行),

这是函数的,把方向的部分,小牛叔称他为:结果产生部分,它能确保程序不会跑偏的代码,如果传入的数字N没有可以被整除的数字,即循环到头了,才会执行这个部分,每一个质数因子都会从这个部分产生,因为最终的结果只能是质数。下图树中的所有叶节点(没有子节点的叶子:2,2,5,7,7),就是从这个部分产生的,当执行到这个部分时,程序不会再往向下递归,所以不会产生下层的树型结构。

再理解,递归的部分(2,3,4行)

通过循环来试因子,如果试到i是N的因子(即N可以被i整除)的话,就返回i的所有因子和 N/i的所有因子 组成的列表,因此下图中所有从上到下的两个箭头对,就代表着这两个递归调用。

通过这个树形解题的过程,您会更加明白!
在这里插入图片描述
在整个程序递归执行时,看起来是从顶980开始向下求解执行,而求解的过程中结果却是从最下层的7,7开始向上汇集。


http://chatgpt.dhexx.cn/article/Mc3kjch5.shtml

相关文章

python递归如何理解

最近在做递归一些相关的东西,发现递归入门很容易,但要具体了解其实现过程,比较难以理解,在这里将自己这几天的摸索记录一下,写知乎的主要目的是为了给自己做笔记,在做笔记的同时,帮助后来人少走…

【Python函数的递归】

递归的定义 函数作为一种代码封装,可以被其他程序调用,当然,也可以被函数内部代码调用。这种函数定义中调用函数自身的方式称为递归。就像一个人站在装满镜子的房间中,看到的影像就是递归的结果。递归在数学和计算机应用上非常强大…

H3C 交换机S5130S软件版本升级

1.通过官网下载软件包 升级的包名为 S5130S_HI-CMW710-R6330.ipe 2. 查看FLASH空间是否足够 <H3C>dir /all Free的空间需要是软件包的2倍大小&#xff0c;例如S5130S_HI-CMW710-R6330.ipe软件包大小为54MB&#xff0c;那么交换机Free的空间需要108M。 空间如果…

H3C 交换机S6520X软件版本升级

1.通过官网下载软件包 升级的包名为 S6520X-CMW710-R6312P02.zip 压缩包里有很多特性包&#xff0c;我们目前就使用 S6520X-CMW710-R6312P02.ipe 2. 查看FLASH空间是否足够 <H3C>dir /all Free的空间需要是软件包的2倍大小&#xff0c;例如S6520X-CMW710-R6312P0…

H3c服务器升级硬盘固件,H3C交换机升级固件版本

二、进入产品支持与服务&#xff0c;找到适配的交换机固件进行下载 三、下载时要求提供用户名密码 用户名&#xff1a;yx800 密码&#xff1a;01230123 四、H3C官方升级说明案例 1.1 实验拓扑(假设SW1上 VLAN 1 的虚地址为10.10.10.1&#xff0c;PC配置同网段地址10.10.10.…

博途V16 更改PLC的型号和固件版本

在线访问&#xff0c;查看硬件PLC的固件版本。 右键&#xff0c;选择更改设备。 选择PLC型号和版本号。

TIA博途_如何更新程序中的指令版本和CPU固件版本?

TIA博途_如何更新程序中的指令版本和CPU固件版本? TIA博途STEP7从V14SP1版本增加新功能:“更新程序”,可以将当前CPU中的程序版本更新至能够使用的最高版本,对于通讯、运动控制等版本经常升级的程序非常适用, 以下进行举例说明: TIA博途STEP7 V13 SP1中组态S7-1200 V4.1版…

TIA PORTAL西门子PLC的CPU固件版本兼容问题

TIA PORTAL西门子PLC的CPU固件版本兼容问题 以S7-1200为例&#xff0c;现在新出的PLC的固件都是V4.4的版本了&#xff0c;而原来的软件如V15.0组态不到V4.4&#xff0c;只能组态到V4.2&#xff0c;在想继续使用V15.0的情况下&#xff0c;这个PLC还可以用吗&#xff1f; 答案是可…

如何在TIA博途中在线更新PLC的CPU固件版本?

如何在TIA博途中在线更新PLC的CPU固件版本? S7-1200PLC最新的V4.6.0版本的固件出来了,本次就以V4.6版本的固件为例,演示如何在博途中对PLC的固件版本进行更新。 (为防止更新过程中出现意外,强烈建议对PLC的程序进行备份!备份!备份!) 如下图所示,打开某个项目,选中PL…

西门子S7-1200如何使用TIA软件更新CPU固件版本

1、先点击上方“可访问的设备”按钮&#xff0c;扫描出当前所连PLC。 2、点击“显示”&#xff0c;在右边目录树中即可显示出所连PLC&#xff0c;点击“在线和诊断”。 3、即可显示出固件版本和上一个使用者所用博图软件版本。 4、打开所连接S7-1200的“在线和诊断”视图&…

软件版本控制流程

1.编写目的 主要针对软件版本的流程, 以确保公司资产得到保护。 2.适用范围 该流程适用于产品研发部门。 3.环境资源 在整个产品生命周期中&#xff0c;以gitlab作为公司主要代码仓库。 4.流程 流程分为版本号定义、版本发布 4.1 版本号定义 4.1.1 版本号规则 采用语义…

康耐视智能相机更新固件版本方式

康耐视智能相机更新固件版本方式 1、 首先下载对应版本的in-sight Explorer软件&#xff0c;软件自带此版本的固件信息 2、 打开软件&#xff0c;将相机与电脑处于同一网段&#xff0c;在系统—将传感器/设备添加到网络 3、 设置好相机的IP 地址 4、 确认相机与电脑在同一网…

keil中查看仿真器固件版本号

1.首先选择仿真器类型 2.然后点击设置&#xff0c;FW Version显示的就是版本号。

如何确定当前的S7-1200PLC使用的具体的博途软件和固件版本?

如何确定当前的S7-1200PLC使用的具体的博途软件和固件版本? 首先,我们要了解,在使用博途软件对S7-1200或1500系列的PLC进行上传或下载等操作时,必须保持软件版本或固件版本的一致性,否则可能会出现意想不到的问题。 那么,如果当前正在使用的PLC或项目程序不是自己做的,…

软考高项笔记 | PERT 三点估算

PERT 三点估算&#xff1a; 期望时间&#xff1a;期望的一个工期&#xff0c;用 T 表示 悲观时间&#xff1a;最糟糕的情况&#xff0c;用 T1 表示 最可能时间&#xff1a;一般的情况&#xff0c;用 T2 表示 乐观时间&#xff1a;最好的情况&#xff0c;用 T3 表示 T &am…

PMP考试【6】三点估算法 PERT计划评审技术

三点估算也称PERT法&#xff0c;在计算每项活动的工期时都要考虑三种可能性&#xff0c;计算最悲观的工 期、最可能的工期、最乐观的工期&#xff0c;然后再计算出该活动的期望工期&#xff0c;PERT法计算的是 期望工期. 用PERT法计算工期&#xff0c;我们必须记住下面三个公式…

软考_2021年11月真题2__三点估算技术

33. 下图表示某项目各个活动关系及乐观、 最可能、 最悲观完成时间&#xff0c;假设各活动的三种完成时间服从分布&#xff0c; 按照三点估算法该项目标准差为 3.2 天&#xff0c;则项目在 ( )完成的概率为 95%。 活动紧前活动乐观时间&#xff08;天&#xff09;最可能…

三点估算工期

三点估算也称PERT法&#xff0c;在计算每项活动的工期时都要考虑三种可能性&#xff0c;计算最悲观的工期、最可能的工期、最乐观的工期&#xff0c;然后再计算出该活动的期望工期&#xff0c;PERT法计算的是期望工期. 用PERT法计算工期&#xff0c;我们必须记住下面三个公式(P…