递归_三要素_基础算法必备

举报
红目香薰 发表于 2022/01/22 23:52:30 2022/01/22
【摘要】 递归_三要素_基础算法必备 目录 第一要素:明确函数作用 第二要素:递归结束条件 第三要素:函数等价关系 第一要素:明确函数作用 对于递归,我觉得很重要的一个事就是,这个函数的功能是什么,他要完成什么样的一件事,而这个,是完全由你自己来定义的。也就是说,我们先不管函数里面的代码什么,而是要先明白,你这个函数是要用来干...

递归_三要素_基础算法必备

目录

第一要素:明确函数作用

第二要素:递归结束条件

第三要素:函数等价关系


第一要素:明确函数作用

对于递归,我觉得很重要的一个事就是,这个函数的功能是什么,他要完成什么样的一件事,而这个,是完全由你自己来定义的。也就是说,我们先不管函数里面的代码什么,而是要先明白,你这个函数是要用来干什么。


  
  1. // 算 n 的阶乘(假设n不为0)
  2. public static int f(int n){
  3. }

这个函数的功能是算 n 的阶乘。我们已经定义了一个函数,并且定义了它的功能是什么,接下来我们看第二要素。

第二要素:递归结束条件

所谓递归,就是会在函数内部代码中,调用这个函数本身,所以,我们必须要找出递归的结束条件,不然的话,会一直调用自己,进入无底洞。也就是说,我们需要找出当参数为啥时,递归结束,之后直接把结果返回,请注意,这个时候我们必须能根据这个参数的值,能够直接知道函数的结果是什么。

例如,上面那个例子,当 n = 1 时,那你应该能够直接知道 f(n) 是啥吧?此时,f(1) = 1。完善我们函数内部的代码,把第二要素加进代码里面,如下


  
  1. // 算 n 的阶乘(假设n不为0)
  2. public static int f(int n){
  3. if(n == 1){
  4. return 1;
  5. }
  6. }

有人可能会说,当 n = 2 时,那我们可以直接知道 f(n) 等于多少啊,那我可以把 n = 2 作为递归的结束条件吗?

当然可以,只要你觉得参数是什么时,你能够直接知道函数的结果,那么你就可以把这个参数作为结束的条件,所以下面这段代码也是可以的。


  
  1. // 算 n 的阶乘(假设n>=2)
  2. public static int f(int n){
  3. if(n == 2){
  4. return 2;
  5. }
  6. }

注意我代码里面写的注释,假设 n >= 2,因为如果 n = 1时,会被漏掉,当 n <= 2时,f(n) = n,所以为了更加严谨,我们可以写成这样: 


  
  1. // 算 n 的阶乘(假设n不为0)
  2. public static int f(int n){
  3. if(n <= 2){
  4. return n;
  5. }
  6. }

第三要素:函数等价关系

第三要素就是,我们要不断缩小参数的范围,缩小之后,我们可以通过一些辅助的变量或者操作,使原函数的结果不变。

例如,f(n) 这个范围比较大,我们可以让 f(n) = n * f(n-1)。这样,范围就由 n 变成了 n-1 了,范围变小了,并且为了原函数f(n) 不变,我们需要让 f(n-1) 乘以n。

说白了,就是要找到原函数的一个等价关系式,

f(n) 的等价关系式为 n * f(n-1),

即:f(n) = n * f(n-1)。

这个等价关系式的寻找,可以说是最难的一步了,如果你不大懂也没关系,因为你不是天才,你还需要多接触几道题,我会在接下来的文章中,找 10 道递归题,让你慢慢熟悉起来。 

找出了这个等价,继续完善我们的代码,我们把这个等价式写进函数里。如下:


  
  1. // 算 n 的阶乘(假设n不为0)
  2. public static int f(int n){
  3. if(n <= 2){
  4. return n;
  5. }
  6. // 把 f(n) 的等价操作写进去
  7. return f(n-1) * n;
  8. }

 至此,递归三要素已经都写进代码里了,所以这个 f(n) 功能的内部代码我们已经写好了。

这就是递归最重要的三要素,每次做递归的时候,你就强迫自己试着去寻找这三个要素。

测试一下这个【阶乘】:【15就接近int最大值了】


  
  1. package test;
  2. /**
  3. *
  4. * @author laoshifu
  5. * 2021年12月8日
  6. */
  7. public class Action {
  8. public static void main(String[] args) {
  9. long start = System.currentTimeMillis();
  10. System.out.println(f(15));
  11. long end = System.currentTimeMillis();
  12. System.out.println("消耗时间:"+(end-start));
  13. }
  14. // 算 n 的阶乘(假设n不为0)
  15. public static int f(int n){
  16. if(n <= 2){
  17. return n;
  18. }
  19. // 把 f(n) 的等价操作写进去
  20. return f(n-1) * n;
  21. }
  22. }

希望能对大家有所帮助。 

文章来源: laoshifu.blog.csdn.net,作者:红目香薰,版权归原作者所有,如需转载,请联系作者。

原文链接:laoshifu.blog.csdn.net/article/details/121797194

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。