递归的递与归

1、铺垫

在聊递归前我们先来聊下函数做个铺垫

1.1 函数——任务的切割

1.1.1 没有函数的情况:

主角(程序)从上到下按部就班的完成主线任务
在这里插入图片描述

1.1.2 有函数的情况:

主角(程序)在主线任务执行的中途,要去完成副本任务才能接着往下做主线任务
在这里插入图片描述

1.2 函数——数据的传递

输入(函数参数)与输出(函数返回值)

主角(程序)从主线任务前往副本任务的时候 不是空手的,会带一些装备(函数参数)过去;
完成副本任务后 会带一些战利品(函数返回值) 再回到主线任务接着干。

2、什么是递归?

关于递归的概念网上有大把专业的介绍,这里不做赘述。
下面我用“另类”的说法(给你们讲个故事)尝试介绍下递归:

2.1 这次主角要完成一个奇葩的主线任务:这个主线任务中的副本任务内容和主线任务一模一样!
在这里插入图片描述

!](https://img-blog.csdnimg.cn/direct/69dea001e55c413dad67f2e1c384ea0b.png)

2.2 根据前面铺垫(函数——任务的切割)我们知道:这个主线任务是被切割的,切割的位置是个分界点(传送门)

2.3 分界点前面的任务我们的主角已经完成了,分界点下面的任务暂时不干,先穿越打副本。

2.4 由于副本任务和主线任务一模一样,主角又要重复干一遍上面的过程:任务做“一半”继续穿越。

2.5 那主角要一直不断穿越下去吗?根据前面的铺垫(函数——数据的传递)我们知道: 主角不是空手穿越的,他是带着装备的、是要干活的(不是光穿越不干活),因此我们的主角怀揣着这样的信念:终点(递归出口)一定就在前方,于是不断地穿越不断地执行干活;如果其实前方根本就没有终点,我们可怜的主角就会带着他美好的信念过劳而死(调用栈溢出)

2.6 主角在最后一个副本任务完成后(到达终点),带着他的战利品往回赶(函数——数据的传递),往回赶的过程中还要继续完成分割线的下半部分任务,这个过程中,手中的战利品也会发生变化:可能变得更多,可能发生了磨损

最终带着战利品来到了主环境完成剩下的任务,至此终于完成了主线任务

3、递归的递与归

3.1 将递归任务环境拆分成:“递世界”、“传送门”、“归世界任务”
在这里插入图片描述
3.2 递的过程是正向的,归的过程是逆向的
在这里插入图片描述
3.3 正向数据传递:传参,逆向数据传递:返回结果

在这里插入图片描述
3.4 递归核心:原子任务(需要重复被执行的任务)
我们的主角在递与归的过程中 做着“相似”的任务而不是“相同”的任务,我们将这个任务称之为:原子任务。
为啥是“相似”,而不是“相同呢”?因为“数据的传递” 导致 主角每次执行“原子任务”的时候 带的装备或战利品都不一样!

3.5 递归任务的分类(根据结构分类)
在这里插入图片描述
3.5.1 原子任务放在递世界
这种递归比较简单,因为它是个正向的过程。
比如:遍历算法,我在递世界里就能获取到每一项的值,到了终点后原路返回(这一过程通常不需要再干其他任务)

3.5.1 原子任务放在归世界
这里又分成两种情况:
在这里插入图片描述
先说第二种:不依赖上一次任务的数据传递,这一种也比较简单,因为没有涉及到依赖数据的计算
比如:链表的逆置,先到达递归终点拿到尾节点(逆置后为根节点),然后将尾节点原封不动的在归世界传递。
说明:关于链表的逆置的原子操作 这里不作赘述,大家可以查相关代码,这里只交代下:它的原子操作是放在归世界的。

再来说第一种:依赖上一次任务的数据传递
比如:斐波那契数列、简单的快速排序算法,这种递归是最难的,因为它包括了:逆向、逆向过程中依赖数据的累计计算,如下图:
在这里插入图片描述
主角在归世界的起点拿到了A,然后往回走计算出A+B,依次类推。。。简单概括就是:将上一次的结果(A)参与本次的运算得到新的结果(A+B)

4、如何驯服“递归”?

拿到一个问题,有没有一般性的解决思路?
我这里作个额外总结给大家参考:
在这里插入图片描述
主要看主技能:1、分析问题 2、转化问题 3、实在不会就放弃(不要钻牛角尖)

分析转化递归问题:
1、原子操作是啥?
这一步是最难的,因为要找出问题的一般性解决规律,需要用到数学归纳法来推导,如果问题比较难这边建议直接放弃。

2、原子操作放在递世界还是归世界
如果正向的过程就能得到结果就放在递世界,比如遍历操作,我在正向的过程就能拿到被遍历的每一项;
其他情况放归世界;
放在归世界的原子操作如果还依赖上一次的计算结果,这种情况我们上面说过比较复杂,那我们就用“见微知著”的方式:
从“递的终点,归的起点”(作为逆向调用的第一步)开始分析,倒数第二步在拿到起点的数据后(倒数第二步的切割处)做了啥操作?然后执行倒数第二步的归世界代码又做了啥?依次类推出:最终回到主线任务的切割处会得到啥样的数据。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值