一、递归函数

"""
自己调用自己的函数就是递归
递: 去
归: 回
一去一回就是递归
"""

例、

def digui(n):
print(n,"<====1===>")
if n > 0:
digui(n-1)
print(n,"<====2===>")
digui(5)

代码解析:

"""
# 代码解析:
去的过程:
n = 5 print(5,"<====1===>") 5>0 条件成立-> digui(5-1) => digui(4) 代码阻塞在第13行
n = 4 print(4,"<====1===>") 4>0 条件成立-> digui(4-1) => digui(3) 代码阻塞在第13行
n = 3 print(3,"<====1===>") 3>0 条件成立-> digui(3-1) => digui(2) 代码阻塞在第13行
n = 2 print(2,"<====1===>") 2>0 条件成立-> digui(2-1) => digui(1) 代码阻塞在第13行
n = 1 print(1,"<====1===>") 1>0 条件成立-> digui(1-1) => digui(0) 代码阻塞在第13行
n = 0 print(0,"<====1===>") 0>0 条件不成立 print(0,"<====2===>")
当前这层空间代码已经执行结束
此刻触发回的过程 n = 1 从上一次13行的代码阻塞位置,继续向下执行 print(1,"<====2===>")
n = 2 从上一次13行的代码阻塞位置,继续向下执行 print(2,"<====2===>")
n = 3 从上一次13行的代码阻塞位置,继续向下执行 print(3,"<====2===>")
n = 4 从上一次13行的代码阻塞位置,继续向下执行 print(4,"<====2===>")
n = 5 从上一次13行的代码阻塞位置,继续向下执行 print(5,"<====2===>")
到此,递归函数彻底执行结束.
5 4 3 2 1 0 0 """

1、栈帧空间

# 每次调用函数时,在内存中都会单独开辟一个空间,配合函数运行,这个空间叫做栈帧空间
"""
(1).递归是一去一回的过程,
调用函数时,会开辟栈帧空间,函数执行结束之后,会释放栈帧空间
递归实际上就是不停的开辟和释放栈帧空间的过程
每次开辟栈帧空间,都是独立的一份,其中的资源不共享 (2).触发回的过程
1.当最后一层栈帧空间全部执行结束的时候,会触底反弹,回到上一层空间的调用处
2.遇到return,会触底反弹,回到上一层空间的调用处, (3).写递归时,必须给与递归跳出的条件,否则会发生内存溢出,蓝屏死机的情况.
如果递归层数过多,不推荐使用递归 """

2、举例

2.1、用递归计算n的阶乘

# 常规方法
# 5! = 5*4*3*2*1
def func(n):
total = 1
for i in range(n,0,-1):
total *= i
return total res = func(5)
print(res) # 递归写法
def jiecheng(n):
if n <= 1:
return 1
return n*jiecheng(n-1)
res = jiecheng(5)
print(res)

代码解析:

"""
return 后面的表达式,一定是先计算完在返回
# 代码解析:
# 去的过程:
n = 5 return 5*jiecheng(5-1) => 5 * jiecheng(4)
n = 4 return 4*jiecheng(4-1) => 4 * jiecheng(3)
n = 3 return 3*jiecheng(3-1) => 3 * jiecheng(2)
n = 2 return 2*jiecheng(2-1) => 2 * jiecheng(1)
n = 1 return 1 # 回的过程:
n = 2 return 2*jiecheng(2-1) => 2 * jiecheng(1) => 2 * 1
n = 3 return 3*jiecheng(3-1) => 3 * jiecheng(2) => 3 * 2 * 1
n = 4 return 4*jiecheng(4-1) => 4 * jiecheng(3) => 4 * 3 * 2 * 1
n = 5 return 5*jiecheng(5-1) => 5 * jiecheng(4) => 5 * 4 * 3 * 2 * 1
return 5 * 4 * 3 * 2 * 1 => return 120
"""

2.2、尾递归

"""
自己调用自己,并且非表达式
计算的结果要在参数当中完成. 尾递归无论调用多少次函数,都只占用一份空间,但是目前cpython不支持.
"""
def jiecheng(n,endval):
if n <= 1:
return endval
return jiecheng(n-1,endval*n) res = jiecheng(5,1)
print(res)

代码解析:

"""
# 代码解析:
去的过程
n=5 , endval=1 return jiecheng(5-1,endval*5) => jiecheng(4,1*5)
n=4 , endval=1*5 return jiecheng(4-1,endval*4) => jiecheng(3,1*5*4)
n=3 , endval=1*5*4 return jiecheng(3-1,endval*3) => jiecheng(2,1*5*4*3)
n=2 , endval=1*5*4*3 return jiecheng(2-1,endval*2) => jiecheng(1,1*5*4*3*2)
n=1 , endval=1*5*4*3*2 return endval 回的过程:
n=2 return 120
n=3 return 120
n=4 return 120
n=5 return 120 因为最后一层空间的返回值就是第一层空间的返回值,所有在使用尾递归的时候
不需要考虑回的逻辑过程,就能解决问题.推荐使用.
"""

链接

day15.递归函数的更多相关文章

  1. python 全栈开发,Day15(递归函数,二分查找法)

    一.递归函数 江湖上流传这这样一句话叫做:人理解循环,神理解递归.所以你可别小看了递归函数,很多人被拦在大神的门槛外这么多年,就是因为没能领悟递归的真谛. 递归函数:在一个函数里执行再调用这个函数本身 ...

  2. day15 python lambda函数 递归函数 二分法

    day15 python   一.匿名函数 lambda     1.lambda函数 def func(n):                #普通函数, 功能比较简单, 当函数多的时候, 起名也不 ...

  3. day15 函数的使用方法:递归函数

    这里归纳的知识点主要就是: 浮点数,复数, int,整形:float,浮点数:complx,复数: # 实数: # 有理数 有限小数 1.2 # 无限循环小数 1.23232323232323.... ...

  4. 递归函数(Day15)

    一.递归的定义 在一个函数里面再调用这个函数本身 递归特性 1.必须有一个明确的结束条件 2.每次进入更深一层递归时,问题规模相比于上一次的递归有所减少 二.递归的应用 1.递归函数与三层菜单 men ...

  5. python全栈开发之匿名函数和递归函数

    python 匿名函数和递归函数 python全栈开发,匿名函数,递归函数 匿名函数 lambda函数也叫匿名函数,即函数没有具体的名称.是为了解决一些功能很简单需求而设计的一句话函数.如下: #这段 ...

  6. javascript中的递归函数

    正常的递归函数如下: function factorial(num){ ){ ; }else{ ); } } 这个函数表面看起来还ok,但如果我们执行下面代码就会出错. var jenny = fac ...

  7. JS函数相关及递归函数的使用

    JS函数相关及递归函数的使用 通用js程序: function 函数名(参数列表) { 函数体 } 可使用alert()输出,也可用return返回值. alert与return区别: functio ...

  8. python3--函数(函数,全局变量和局部变量,递归函数)

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

  9. Python之路 day3 递归函数

    #!/usr/bin/env python # -*- coding:utf-8 -*- #Author:ersa """ 在函数内部,可以调用其他函数.如果一个函数在内 ...

随机推荐

  1. 数组中出现次数超过一半的数字(剑指offer-28)

    题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...

  2. Lambda 表达式遍历集合时用remove方法删除list集合中满足条件的元素问题

    一:循环遍历list集合的四种方式 简单for循环 iterator循环 增加for循环 Lanbda表达式 二:四种遍历方式的用法示例 //简单for循环 List<SalaryAdjustm ...

  3. python入门009

    目录 四.列表 1.定义:在[]内,用逗号分隔开多个任意数据类型的值 2.类型转换:但凡能被for循环遍历的数据类型都可以传给list()转换成列表类型,list()会跟for循环一样遍历出数据类型中 ...

  4. C++快速读写

    1.主函数的最前面加入这个 std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); 2.这是一个读入数字的快读 inline int read() ...

  5. 解决Linux搜狗输入法工具栏无法移动

    问题的出现 前两天一位朋友(@午后下午茶)发现一个有趣的情况: 为了复现bug,我把自己的输入法工具栏也挪到了顶栏,果然也无法挪动了 解决方法 原理不明,但解决方法很简单. 如图所示,随便找个输入框打 ...

  6. Pop!_OS安装与配置(三):系统美化

    Pop!_OS系统美化 首先上效果图,美化完是这样的: 那么接下来就一步步进行美化吧 主要参考:Ubuntu 18.04 美化配置--leo.rd 1.安装tweak sudo apt install ...

  7. 数据可视化之powerBI基础(二十)Power BI度量值和新建表,有什么异同?

    https://zhuanlan.zhihu.com/p/101812525 ​PowerBI中,有三个地方可以使用DAX,分别是度量值.新建列和新建表,这三个功能并成一排摆放在这里,如图所示, 之前 ...

  8. Python之爬虫(十四) Scrapy框架的架构和原理

    这一篇文章主要是为了对scrapy框架的工作流程以及各个组件功能的介绍 Scrapy目前已经可以很好的在python3上运行Scrapy使用了Twisted作为框架,Twisted有些特殊的地方是它是 ...

  9. mysql中常见约束

    #常见约束 /* 含义:一种限制,用于限制表中的数据,为了保证表中的数据的准确和可靠性 分类:六大约束 NOT NULL:非空,用于保证该字段的值不能为空 比如姓名.学号等 DEFAULT:默认,用于 ...

  10. Python Ethical Hacking - MAC Address & How to Change(1)

    MAC ADDRESS Media Access Control Permanent Physical Unique Assigned by manufacturer WHY CHANGE THE M ...