浅显易懂解释递归

1:递归的传统理解

如果一个问题能够递归,那么:

当前问题能够分解为少量结构相同或相似的子问题组合,子问题同样可以按当前问题的分解方法分解直至到问题边界

解出边界解

从边界往回一层一层得子问题的解,最终得到主问题解

2:浅显易懂的解释

现在来解决一个大问题,问题规模为n。

太难了,一下子解决不动,没关系,试试能不能解决更小规模如n-1的子问题,

还是太难了,一下子解决不动,没关系,试试能不能解决更小规模如n-2的子问题,

......

还是太难了,一下子解决不动,没关系,试试能不能解决更小规模如n=1的子问题,

能啊,只要return 10;(举例子)

在这个过程中,我们不一下解决规模为n的巨大问题,而是不断简化问题规模并发问能否解决此时更简化的问题(即上文中从规模n开始,不断缩减问题规模为n-1,n-2,......,并尝试求解的过程)。

这个不断简化并尝试求解的过程持续进行,直至我们能轻易解决某个很简化的问题(如上文从规模n不断化简直至n=1时,我们能轻松的得到解,这个解可能来源于题意)。

此时这个把规模为n的巨大问题化简的过程就完成了。化简到达了边界,上文的n=1就是边界条件,return 10;的语句就是边界的解。

以上过程为从外到里,逐层化简问题,不断尝试,最终得到边界解。

而这个边界解会给我们带来巨大的回馈。

此时得到了规模为n=1的子问题的解,也就是我们的边界解,

惊喜地发现,问题规模为n=2的子问题可以解决了,只要return 2*(n=1时问题的结果);(举例子,假设随着问题规模的扩大,某问题规模如i的问题的解等于问题规模为i-1的问题的解的2倍)

继续向外,惊喜地发现,问题规模为n=3的子问题可以解决了,只要return 2*(n=2时问题的结果);

......

继续向外,惊喜地发现,问题规模为n的子问题可以解决了,只要return 2*(n=n-1时问题的结果);

以上整个过程,是从最大规模出发,由外向内化简原问题为一个个子问题,最终得到边界解,再由边界出发由内向外逐层得到各个子问题的解,最终得到最大规模问题的解。

3:配合例子食用

举个简单例子,求阶乘。要求解100的阶乘

从最大规模n=100出发,由外向里化简原问题为一个个子问题

n=100,我一下解不出来,没关系,试试n=99子问题能不能解,

n=99,我一下解不出来,没关系,试试n=98子问题能不能解,

......

最终得到边界解

试试n=1子问题能不能解,能解,return 1;

再由边界出发由内向外逐层得到各个子问题的解,

发现,n=2子问题能解了,只要return 2*(n=1时问题的解);

发现,n=3子问题能解了,只要return 3*(n=2时问题的解);

......

最终得到最大规模问题的解

发现,n=100原问题能解了,只要return 100*(n=99时问题的解),

 

4:简单理解后,如何写出递归:

4.1先得到边界解

分析原问题的小规模形式是怎样的,不断简化原问题规模并尝试求解,直至到最小规模也就是我们的边界,解出来即可。

比如,打印n行数字,它的小规模形式为打印更少行数字,不断化简并尝试打印n-1行,n-2行......,都不好解决,直至n=1可解,打印一个1(举例)即可。

n=1是我们的边界,打印一个1是这个边界的解。

4.2用子问题的解设计递归体

我们得到边界解了。通过边界解的不断返回,能得到各个规模子问题的解。

也就是说,各个规模子问题的解是已知的,要积极主动拿着用。

现在来设计递归体。

只考虑当前规模n,而n-1规模已经解决,我拿来用。

比如,阶乘(n)的递归体为

{

ruturn 阶乘(n-1);//积极主动地用子问题的解

}

在下边代码中,可以看出,主动使用子问题的解是很重要的。否则,递归不成立。

4.3成功

 

类型 fun(规模 n){
    if(n==边界){
        return 边界解;
    }
    else{//递归体,假设更小规模已解决,只考虑当前规模时,如何解决问题
        只考虑当前规模的解题过程;
        ......;        
        只考虑当前规模的解题过程;   
        //积极主动用子问题的解,例如fun(n-1)是子问题的解,拿来做乘法(举例子)
       ruturn n*fun(n-1);
        //用子问题的解,这个行为本身,就是在递归调用自己。
        //不用子问题的解,递归不存在。
    
    }

}

 

 

 

递归中的return可以用于递归的终止条件和返回值的传递。当递归函数达到终止条件时,会返回最底层调用的函数的返回值。然后,上一层的函数会继续执行剩余的代码,并使用下一层返回的值进行计算。这个过程会一直循环,直到返回到最上层函数,结束整个递归过程。\[2\] 举个例子来说明,假设有一个递归函数Sum,用于计算从1到n的累加和。在递归函数中,当n小于等于1时,返回n作为终止条件。当n大于1时,递归调用Sum函数,并将n减1作为参数,然后将返回的值与n相加作为当前层的返回值。这样,每一层的返回值都会被上一层使用,直到最上层函数得到最终的返回值。\[2\] 另外,递归也可以不使用return来传递值。在一些情况下,可以使用参数传递的方式来实现递归。例如,在一个数组中查找特定元素的递归函数中,可以将结果存储在参数中,并在递归调用时传递给下一层函数。这样,每一层的函数都可以修改参数的值,实现递归过程中的数据传递。\[3\] #### 引用[.reference_title] - *1* [java递归之return](https://blog.csdn.net/weixin_43850103/article/details/108234970)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [关于递归中return的理解(最浅显易懂)](https://blog.csdn.net/weixin_44220976/article/details/103817707)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [js 中递归加上return和没return的区别](https://blog.csdn.net/qitianhuoshen/article/details/105699601)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值