一、概述
上一期,我们是具体学习了File类的一些概念基础知识点,以及对于该类的常用方法进行了一个全量举例演示,这也是考虑到有的小伙伴在阅读的同时,没有时间去实际测试,所以我也就顺带的给大家去做了实例演示,一来给需要的小伙伴能有个标准答案可观摩,二来就是为了方便有些读者没有实操场地从而可以看我的列举并对于每一个实例都有一个对应的截图,这就很为读者们参考了。而这一期,我要给你们聊点什么呢?这是个问题,刚下班到家,头有点迷糊,但是今天的文章还没更新, 所以需要给你们一个交代不是。
所以这一期,我跟大家聊聊递归吧!以前在刷题的时候经常有用到递归思路,所以对于大家而言,递归思想也是需要掌握的。
废话不多说,咱这就开始干正事!
二、本期教学目标
- 掌握何为递归
- 能够使用递归的方式计算一些阶乘
- 能够简单谈谈递归的优劣
- 能够谈谈递归会导致内存溢出隐患的问题
- ...
三、正文
1、概念
一开始听到这么个词,肯定不是很理解,那你们字面理解递归二字应该是啥意思呢?其实呢,也很好理解,递归就是指在当前方法内自己调用自己这么种现象,就被称为递归。
2、递归分类
递归也分类,一般递归分为直接递归和间接递归。
- 直接递归:指方法自身调用自身。
- 间接递归:值相互之间调用,比如a方法调用b方法,b方法调用c方法,c方法调用a方法。
3、递归优劣比较
需要注意的是,递归容易造成死循环,也就是我提到的内存溢出问题,所以对于递归要有条件限定,保证递归能够正常结束,而不是一直死循环自我调用跳不出来。
其次就是递归需要限定条件,但是递归次数不能太多,否则也很有可能发生栈内存溢出。
最后就是,对于构造方法,是不允许递归的。
4、解释内存溢出隐患问题
这问题也就是我上述提到的“死循环”,既然要用递归,那一定要限定条件及终结递归的条件,保证递归能跳出,否则一直递归下去,肯定得把内存占满,导致内存溢出。
四、实例演示
接下来,就是实战环节了,我先问大家个问题?累加如何实现?遍历嘛?按次数遍历,这是最普通的做法?那我要是说到递归呢?我说就可以用递归来解决。
说到累加,累乘,这类题若不要求时间复杂度,那最简便快捷的方式就是采用递归的实现方式,所以接下来,我给大家诺列几道递归题,结合实际场景来运用递归思想,帮助大家能快速吸收掌握。
1、实例题1
请计算1-10之间的累加和。要求用递归思想实现。
分析:何为累加,就是前两数之和与后一个相加,然后之和接着与后一个数进行累加,就比如num(n) = num(n-2)+num(n-1),所以你看啊,这里就其实满足递归的创建了,累加的操作就可以定义成一个方法,然后递归调用。这样说你们能理解么?不理解也没事,我接下来带着大家去实现一遍这道题吧。
代码如下:
第一步,我们先来找找规律,从规律中找到方法如何定义,具体如下:
sum(1) = num1
sum(2) = sum(1) + num[2]
sum(3) = sum(2) +num[3]
sum(4) = sum(3) +num[4]
sum(5) = sum(4) +num[5]
...
sum(n) = sum(n-1) +num[n]
所以,这规律完全具备递归条件,接下来,你们知道递归函数怎么写了吗?
代码如下:
//递归求和
public int getSum(int num) {
/**
* 方法的出口,num总有为1的时候。
*/
if (num == 1) {
return 1;
}
//num不为1时,方法返回 num +(num‐1)的累和
//递归自我调用getSum()
return num + getSum(num - 1);
}
然后我们再来写个测试类,调用该getSum()函数,然后入参我们传10。
@Test
public void test() {
//求1-10累加和
System.out.println("1-10累加和为:" + this.getSum(10));
}
具体运行控制台打印:
打印结果是不是对的啊。若你不是很清楚它具体的执行的方式,我还可以给你打印一下执行过程。
我是直接将num给打印了,你们看,其实递归是执行了10次,这样你们总能理解了吧。
2、实例题2
请计算10的阶乘。要求用递归思想实现。
分析:可以先找找规律,也是有帮你如何实现累乘方法。
sum(1) = num1
sum(2) = sum(1) * num[2]
sum(3) = sum(2) * num[3]
sum(4) = sum(3) * num[4]
sum(5) = sum(4) * num[5]
...
sum(n) = sum(n-1) +num[n]
那么n的阶乘拆开应该为:n! = n * (n‐1) *...* 3 * 2 * 1
所以代码实现也很简单。
@Test
public void test() {
//求10!
System.out.println("10!结果为:" + this.getSum(10));
}
//递归求阶乘
public int getSum(int num) {
/**
* 方法的出口,num总有为1的时候。
*/
if (num == 1) {
return 1;
}
//递归自我调用getSum()
return num * getSum(num - 1);
}
具体运行控制台打印: