JavaSE基础(五)---递归

目录

一、递归的基本概念

二、递归执行的过程分析

 三、递归练习

 1、递归依次按顺序打印1234

2、递归求 N 的阶乘


一、递归的基本概念

对于有接触过c语言的,对递归应该是具有一定的了解,在Java中的递归跟c语言中没什么很大的区别。

递归这种思想,大多可以用在一些编程里面,帮助我们更灵活的实现功能,但有时反而会使代码运行效率降低,在什么场合中使用,需要我们通过不断刷题和学习,培养我们的思维。对我们以后编程能力的提升有很大的帮助!


 递归:

        一个方法,在其本身内执行时又调用了自身的方法,就被称为”递归“。

【注意:”递“和”归“是两个动作

进行递归时,必须要有一个可以结束的条件和调用自己本身,否则将不断调用本身,直到栈溢出!

简单递归代码示例:

        1+2+3+...+10

 

可能当当代码有点难理解期间”递“和”归“的过程,接下来我将把递归的过程拆开分析。


二、递归执行的过程分析

我们在分析递归的过程时,以平时的纵向思考可能难以理解,反之以一种横向思考,反而相得益彰。

需要从两个方向点着手:(1)递归的起始条件或终止条件;

                                        (2)方法执行结束再调用本身方法流程(推导递推公式)

 以上面的代码进行过程分析:

(1)在方法第一次调用时,我们传过去的参数为10,进行if判断后(不满足等于1),执行下面的return语句,而return语句又包含了本身方法  return 10+backOf(9);之后就会再进行第二次调用,但这次传过去的参数变成了9,以此不断往后反复调用.

 

(2)在到2+backOf(1)时,backOf(1)的方法调用,其方法内部满足(n==1),返回一个1给该方法backOf。

 (3)之后会不断进行”归“的过程,直到方法结束.

期间过程:

1.     10+backOf(9)

2.     10+9+backOf(8)

3.     10+9+8+backOf(7)

4.     10+9+8+7+backOf(6)

5.      10+9+8+7+6+backOf(5)

6.      10+9+8+7+6+5+backOf(4)

7.      10+9+8+7+6+5+4+backOf(3)

8.      10+9+8+7+6+5+4+3+backOf(2)

9.      10+9+8+7+6+5+4+3+2+backOf(1)

10.      10+9+8+7+6+5+4+3+2+1

 

 程序依此进行后,最终结果即为1+2+3+...+10=55 

【总结】:

在上面这个代码递归的过程中:

  1. 我们要先找出递归过程中的起始位置,以上面代码为例,n==1(是判断返回的终止条件,从某种意义上来看也算起始条件),如果连该条件都找不到,就无法实现递归,不能无限制地调用本身,必须有个出口
  2. 找到之后,还得根据一定的自身调用(此代码中,不满足等于1,继续进行调用)进行依次传递(递归前进段)。
  3. 最关键的还是,要理解清楚递归, 必须先理解清楚 "方法的执行过程", 尤其是 "方法执行结束 之后, 回到调用位置继续往下执行".依次进行”归“后,将各个方法的返回值进行相加,最后返回到主方法内。

 

 三、递归练习

 1、递归依次按顺序打印1234

要想依次打印出每一位数,首先可以联想到取余的方法,然后利用除法将位数减少,再不断提取每一位。

可如果是要求递归的话,必须要有一个终止条件,在调用本身的某一处停止后返回。

代码示例: 

public class Review {
    public static void Print(int n) {
       if(n<10) {
           System.out.print(n+" ");   //当调用该值小于10,说明该值已经除完
           return;
       }
       Print(n/10);                   //调用到最后从最高位开始依次打印
       System.out.print(n%10+" ");    //执行打印到最低为
    }
    public static void main(String[] args) {
      Print(1234);
    }
}

该处递归过程很好理解,无非就是先找到终止条件(最高位1),然后以它判断后再调用本身,每一次调用就除10,减少一位后接打印其取余。

(1) n=1234  ---->    Print(1234/10)  [123]

                              System.out.print(1234%10+" ");     [4]

(2)n=123 ---->  Print(123/10)  [12]

                               System.out.print(123%10+" ");   [3]

(3)n=12 ---->  Print(12/10)  [1]

                               System.out.print(12%10+" ");   [2]

(4)n=1 ---->  n<10    System.out.print(1+" ");   [1]

                               return ; 

条件里的return必不可少,否则递归停不下来。

又因为调用方法在每次打印取余前面,最后是从1开始打印,依次最后到打印4。

 

2、递归求 N 的阶乘

代码示例:

import java.util.Scanner;

public class TestDemo6 {public static int addsum(int n) {
        if(n==1) {
            return 1;
        }
        return addsum(n-1)*n;
    }

    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入N:");
        int n=scanner.nextInt();
        System.out.println(n+"的阶乘为:"+addsum(n));
    }
}

只要知道着手方向,再根据终止条件和循环调用的边界,像这类的简单递归都是很好理解的。 

像此处的阶乘递归,也就是不断调用自身的下一个数,到最后为1的时候返回1,其结果即为10*9*8*7*6*5*4*3*2*1=120

 


总结:

        递归虽然很方便的让我们能更灵活、更容易的实现所想要的功能运算,但每一次递归都会开辟一个空间,随着递归不断进行,递归会开始力不从心,在某一时刻造成内存负担,使我们运行的效率降低。不是所有的运算程序都适用递归,比如斐波那契数列为例,如果采用递归的话,会随着所找的第N项,不断进行大量重复的递归,加重内存负担,大大降低了程序的执行速度。

        递归有递归的优点(简洁),也存在缺点(代码难以理解,有时随着代码的复杂程度会更难理解),因此我们在平时要善用递归,不能说想用就用。

        但也不乏一些特殊情况,必须得使用递归才可以的程序(比如二叉树)

        而对于递归的题型,不是就上面如此简单,以后我们还会碰到更加难以理解的递归程序,因此需要我们不断刷题总结,提升,培养自己的思维能力,才能事半功倍。

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星河栀染

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值