Python---函数递归

编程思想:如何利用数学模型,来解决对应的需求问题;然后利用代码实现对应的数据模

算法:使用代码实现对应的数学模型,从而解决对应的业务问题

程序 = 算法 + 数据结构

在我们经常使用的算法中,有两种非常常用的算法:递推算法 + 递归算法,专门用于解决一些比较复杂,但是拆分后相似度又非常高的程序。

递推算法

递归算法:递推算法是一种简单的算法,即通过已知条件,利用特定条件得出中间推论,直至得到结果的算法。递推又分为顺推和逆推。

顺推:通过最简单的条件,然后逐步推演结果

逆推:通过结果找到规律,然后推导已知条件

递推算法案例:斐波那契数列

1 1 2 3 5 8 13 21 ...

① ② ③ ④ ⑤ ⑥ ...

第1位为1,第2位为1,第3位为2 = 1 + 1,第4位为3 = 2 + 1,依次类推...第n位结果为多少?

f(n) = f(n-1) + f(n-2)

提出问题:求斐波那契数列第15位的结果?

分析:f(15) = f(14) + f(13)

f(14) = f(13) + f(12)

f(13) = f(12) + f(11)

...

f(4) = f(3) + f(2) = 3 + 1

f(3) = f(2) + f(1) = 2

f(2) = 1

f(1) = 1

递推算法:使用while循环或for循环


复制代码
# 递推算法:根据已知条件,求结果(或者根据结果求未知条件)
def recusive(n):
    """ 返回斐波那契数列某一位(n>=1)的结果 """
    if n == 1 or n == 2:
        return 1
    # 开始递推f(3) = f(2) + f(1)  f(4) = f(3) + f(2) ... f(15) = f(14) + f(13)
    dict1 = {1:1, 2:1}
    for i in range(3, n+1):
        # f(3) = f(2) + f(1)
        # f(i) = f(i-1) + f(i-2)
        dict1[i] = dict1[i-1] + dict1[i-2]
    return dict1[n]

# 函数调用
print(recusive(15))

什么是递归算法

程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。

① 简化问题:找到最优子问题(不能再小) ② 函数自己调用自己


复制代码
def func():
    # 自己调用自己
    func()


func()

递归两种重要的元素

递归有两个非常重要的概念:

① 递归点:找到解决当前问题的等价函数(先解决规模比当前问题小一些的函数,依次类推,最终实现对问题的解决) => 有递有归

② 递归出口:当问题解决的时候,已经到达(必须存在)最优问题,不能再次调用函数了

注:如果一个递归函数没有递归出口就变成了死循环

编写递归三步走

① 明确你这个函数想要干什么

如:求斐波那契数列

② 寻找递归结束条件

如:就是在什么情况下,递归会停止循环,返回结果

③ 找出函数的等价关系式

如:斐波那契数列,第n位 f(n) = f(n-1) + f(n-2)

案例1:使用递归求斐波那契数列

第一步:明确这个函数想要干什么(先定义出来,明确调用方式)


复制代码
# 斐波那契数列 1 1 2 3 5 8 13 21 ...
def f(n):
    # 编写递归代码求第n位的结果

# 调用函数
print(f(15))  # 610

第二步:寻找递归的结束条件


复制代码
# 斐波那契数列 1 1 2 3 5 8 13 21 ...
def f(n):
    # 编写递归代码求第n位的结果
    if n == 1 or n == 2:
        return 1

# 调用函数
print(f(15))  # 610

第三步:找出函数的等价关系式(最关键的一步)


复制代码
# 斐波那契数列 1 1 2 3 5 8 13 21 ...
def f(n):
    # 编写递归代码求第n位的结果
    if n == 1 or n == 2:
        return 1
    # 找出与斐波那契数列等价的关系式
    return f(n-1) + f(n-2)

# 调用函数
print(f(15))  # 610

案例2:使用递归求N的阶乘(如n=100)

阶乘是什么?一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,如:n!=1×2×3×...×(n-1)×n

1! = 1

2! = 1x2 = 2

3! = 1x2x3 = 6

4! = 1x2x3x4 = 24

...

n!=1×2×3×...×(n-1)×n

第一步:明确这个函数要做什么以及定义函数以及调用方式


复制代码
def f(n):


# 编写递归条件

print(f(100))

第二步:寻找递归的结束条件


复制代码
def f(n):
    # 编写递归结束条件
    if n <= 2:
        return n
    # ...递归等式
print(f(100))

第三步:编写递归等价公式(自己要调用自己)

等价公式 = 找规律

1! = f(1) = 1

2! = f(2) = 2

3! = f(2)x3 = 6

4! = f(3)x4 = 24

...

n!= f(n-1) * n


复制代码
def f(n):
    # 编写递归结束条件
    if n <= 2:
        return n
    # ...递归等式
    return f(n-1) * n
print(f(100))

案例3:面试题 => 猴子吃桃问题

猴子吃桃问题。猴子第1天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第2天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半另加一个。到第10天早上想再吃时,就只剩下一个桃子了。求第1天共摘了多少个桃子

第一步:确定函数主要要完成什么功能,需要传递哪些参数,确认调用方式


def f(n):

编写递归代码

调用f函数

print(f(1))


第二步:编写递归的结束条件(出口)


第一步:确定函数功能

def f(n):

第二步:编写递归结束条件(出口)

if n == 10:

return 1

调用函数

print(f(1))


第三步:找出与这个问题相等的等式关系

求桃子的剩余数量?假设法:假设有10个桃子

第1天,10个桃子吃一半,10/2 = 5 + 1 = 6

第2天,4个桃子吃一半,4/2 = 2 + 1 = 3

第3天,再想吃剩1个

第n天,总剩余桃子的数量 = (第(n+1)天桃子的剩余桃子的数量 + 1) * 2


复制代码
# 第一步:确定函数功能
def f(n):
    # 第二步:编写递归结束条件(出口)
    if n == 10:
        return 1
    # 第三步:寻找与这个问题相似的等价公式
    return (f(n+1) + 1) * 2

# 调用函数
print(f(8))

相关推荐
卷无止境7 分钟前
Python 异常处理:从入门到工程实践
后端·python
garuda herb9 分钟前
生成专题页Blog--建立并返回 MySQL 数据库连接
python·mysql
ONE_SIX_MIX13 分钟前
qwenpaw-plugin-file-tools QwenPaw增强文件工具 更新 v1.1.1
python·qwenpaw
AOwhisky17 分钟前
Python 学习笔记(第五期)——组合数据类型:列表、元组、集合与字典精讲——核心知识点自测与详解
开发语言·笔记·python·学习·云计算
今心上35 分钟前
关于d2l中train_ch3以及softmax中图在pycharm中显示不出来的解决方案
深度学习·机器学习·pycharm
码农学院35 分钟前
GEO与SEO协同:从传统搜索到生成式搜索的平滑迁移路径
服务器·前端·python
程序员羽痕35 分钟前
基于 Django + PyTorch 的中文字体识别系统
pytorch·python·django
灯澜忆梦9 小时前
GO_并发编程---定时器
开发语言·后端·golang
-银雾鸢尾-10 小时前
C#中的StringBuilder相关方法
开发语言·c#
-银雾鸢尾-10 小时前
C#中结构体与类的区别;抽象类与接口的区别
开发语言·c#