递归完成斐波拉契--函数递归与栈

什么是递归

递归是一种重要的程序设计方法。简单的说,若在一个函数、过程或数据结构的定义中又应用了它自身,则这个函数、过程或数据结构称为是递归定义的,简称递归。

什么是栈

栈是一种数据结构…略

栈与递归的关系

使用计算机实现递归,其实是一种栈的应用

实战

递归完成斐波拉契前20项。关键代码加上注释。
斐波拉契数列:1 1 2 3 5 8 13……(第一项和第二项为1,从第三项开始其值是前两项之和)

python代码

# 思路
'''
0.了解斐波那契数学逻辑
1.使用函数递归调用的出栈时的返回值作为斐波那契值
2.使用函数递归调用时的出栈顺序作为斐波那契数列的顺序
3.使用一个li_printed列表保存已打印项,避免重复打印
'''

li_printed = []  # 定义一个列表存打印过的斐波那契第n项


def print_Fib(n):
    '''打印斐波那契数列前n项'''
    if n == 1:  # 本递归函数最终需要的出口之一
        if n not in li_printed:  # 当n=1时函数递归结束,print_Fib(1)会出栈,此时打印斐波那契第一项的值
            li_printed.append(n)  # 会打印第一项的值,把第一项添加到已打印列表
            print(1, end='\t')
        return 1
    if n == 0:  # 本递归函数最终需要的出口之一
        return 0
    x = print_Fib(n - 1) + print_Fib(n - 2)  # 斐波那契的数学关系,第n项的值等于前两项的值之和
    if n not in li_printed:  # 判断第n项是否打印过,如果未打印则执行下面的函数进行打印
        li_printed.append(n)  # 会打印第n项,把n的值传入已打印列表
        print(x, end='\t')  # 打印第n项的值
    return x  # 函数返回第n项的值

print_Fib(20)

知识点:

  1. 递归的定义,以及如何使用递归完成一个任务
  2. 递归在内存中的入栈和出栈原理
  3. 列表方法( list.append() )可以在函数内直接使用也能够改变列表的值,不用global声明。其原理是系统从函数内向外寻找list的地址,函数内没有list变量,则最终找到全局变量list,再使用全局变量list的地址进行相应方法。同样不用声明的还有字典等可变数据类型
  4. 递归的出口。
  5. 递归中使用return递归。return后面是需要return的东西,层层接收返回,返回即退出

简要解析递归入栈与出栈

Fib代码:

def Fib(n):
    '''斐波那契第n项值'''
    if n == 1:  # 本递归函数最终需要的出口之一
        return 1
    if n == 0:  # 本递归函数最终需要的出口之一
        return 0
    return Fib(n - 1) + Fib(n - 2)  # 函数返回第n项的值
    
Fib(5)

以Fib(5)为例:
Fib(5)入栈,Fib(4)入栈,Fib(3)入栈,Fib(2)入栈,Fib(1)入栈,Fib(1)出栈,Fib(0)入栈,Fib(0)出栈,Fib(2)出栈,Fib(1)入栈,Fib(1)出栈,Fib(3)出栈,Fib(2)入栈,Fib(1)入栈,Fib(1)出栈,Fib(0)入栈,Fib(0)出栈,Fib(2)出栈,Fib(4)出栈,Fib(3)入栈,Fib(2)入栈,Fib(1)入栈,Fib(1)出栈,Fib(0)入栈,Fib(0)出栈,Fib(1)入栈,Fib(1)出栈,Fib(3)出栈,Fib(5)出栈,函数结束

如果在函数内打印,则打印顺序就是出栈顺序,将上列出栈顺序排列一下:

  • Fib(1)出栈,Fib(0)出栈,Fib(2)出栈,Fib(1)出栈,Fib(3)出栈,Fib(1)出栈,Fib(0)出栈,Fib(2)出栈,Fib(4)出栈,Fib(1)出栈,Fib(0)出栈,Fib(1)出栈,Fib(3)出栈,Fib(5)出栈

Fib(0)仅作为函数出口去除掉:

  • Fib(1)出栈,Fib(2)出栈,Fib(1)出栈,Fib(3)出栈,Fib(1)出栈,Fib(2)出栈,Fib(4)出栈,Fib(1)出栈,Fib(1)出栈,Fib(3)出栈,Fib(5)出栈

其值分别对应:

  • 1,1,1,2,1,1,3,1,1,2,5
    在函数内添加打印测试一下:
def Fib(n):
    '''斐波那契第n项值'''
    if n == 1:  # 本递归函数最终需要的出口之一
        print(1,end='\t')
        return 1
    if n == 0:  # 本递归函数最终需要的出口之一
        return 0
    x = Fib(n - 1) + Fib(n - 2)
    print(x,end='\t')
    return x  # 函数返回第n项的值


Fib(5)

在这里插入图片描述
结果一致。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值