关于递归的学习

前言

递归是那种一眼看上去很简单,但是一仔细想就越想越乱的问题

一. 递归三要素

1.1 递归的定义

形参,返回值,返回值的含义

1.2 递归表达式

如何把大问题拆解成小问题

1.3 递归出口

在什么情况下return

1.4 讨论

为什么递归出口要放到递归表达式前面????
A:解答这个问题需要捋清递归问题的执行流程。递归函数的结构一般是:
递归出口
操作x
递归表达式
操作y
(1)第一次进入递归函数,会执行递归调用之前的所有操作,以及递归调用本身。
(2)往后都是如此,递归调用之前的所有操作,以及递归调用本身。不执行递归调用之后的操作
(3)执行到最后一次递归调用,进入递归函数,递归出口条件满足,return.不会执行递归出口之后的递归调用。
(3)执行最后一次递归调用之后的操作,然后return
(4)执行上一次递归调用之后的操作,然后return
(5)以此类推

总结起来就是,在满足递归出口条件之前,不会执行递归调用之后的操作。
要将递归函数分成递归调用之前和之后

假设出口放到递归调用之后,那么无论如何都执行不到递归调用之后的操作,也就永远遇不到出口,最终导致递归深度溢出

二. 递归的分类

2.1 单向递归

2.1.1 打印整数

从没想过打印整数也能改成递归。但仔细一想,递归和迭代本就不是泾渭分明,递归都可以改成迭代,而反之则不然

这确实是两种思想啊

(1)递归定义。一个函数必然有一个功能,递归和迭代都是一样的,打印从1-n的整数。传入的参数都是n,什么都不需要返回,在函数中完成相应的打印操作即可
(2)递归表达式。按照一贯思路,对递归函数的定义进行拆解,要打印1-n的整数,可以先打印n,再打印1-n-1的整数,以此类推。也就是将1-n-1的打印任务交给其他函数去完成
(3)递归出口。如果…,就不再执行后面的操作了,也就不会再进行递归调用了。迭代里边有循环结束的条件,递归是类似的,递归出口条件满足之后,也就不会再执行之后的递归调用了

def digui(n):
    if n < 1:
        return
    digui(n - 1)
    print(n)

三. 内存

在这里插入图片描述
至少java和python遵循上述的内存结构,C++就把某些引用数据类型放到栈空间,这有隐患

3.1 函数调用栈

第一个进入“圆筒”的是main函数,每发生一次新的函数调用,就会有一个新函数进入“圆筒”,正在执行的就是最上面的函数,一个函数执行完毕,就会被拿出来

四. 参数传递

在这里插入图片描述
这三种我都实践过,C++是最原始的那种,三种都有,还保留了越写越乱的指针

4.1 值传递

相当于创建一个新的变量,把值拷贝一份,修改新的变量原来的变量不会受到影响。这已经非常熟悉了。有时候为了避免这一点,还得要用一个引用进行包装

java和c++都you基本数据类型,python不一样,但是python的不可变类型的传递可以被视作值传递,像列表的传递就是一种引用传递

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值