系统:Win10
Java:1.8.0_333
IDEA:2020.3.4
1.概述
递归:指在当前方法内调用自己的这种现象
递归的分类:递归分别为两类:直接递归和间接递归
直接递归:方法自身调用自己
间接递归:如A方法调用B方法,B方法又调用A方法
注意事项
递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出
在递归中虽然有限定条件,但是递归次数不能太多,否则也会发生占内存溢出
构造方法,禁止递归
public class RecursionDemo01 {
public static void main(String[] args) {
// a();
b(1);
}
/*
3.构造方法,禁止递归
编译报错:构造方法时创建对象使用的,不能让对象一直创建下去
*/
public RecursionDemo01() {
// RecursionDemo01();
}
/*
1.递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出
报错:Exception in thread "main" java.lang.StackOverflowError
*/
private static void a() {
System.out.println("执行a方法");
a();
}
/*
2.在递归中虽然有限定条件,但是递归次数不能太多,否则也会发生占内存溢出
报错:Exception in thread "main" java.lang.StackOverflowError
*/
private static void b(int i) {
System.out.println(i);
if (i == 20000) {
return;
}
b(++i);
}
}
2.递归累加求和
要求:计算1到n的和
分析:n的累和 = n + (n-1)的累和,所以可以把累和的操作定义为一个方法,递归调用
实现代码
public class RecursionDemo02 {
public static void main(String[] args) {
// 计算1-n的和,使用递归完成
int n = 6;
// 调用求和方法
int res = getSum(n);
// 输出结果
System.out.println(res);
}
/**
* 通过递归算法实现求累加和
* @param n 需要累加到的最大值
* @return 返回最终的累加和
*/
private static int getSum(int n) {
/*
n为1的时候,返回1
*/
if (n == 1) {
return 1;
}
/*
n不为1的时候,递归调用getSum方法
*/
return n + getSum(n-1);
}
}
运行结果
代码执行图解
提示:递归一定要有条件限定,保证递归能够停止下来,次数不要太多,否则会发生栈内存溢出
3.递归求阶乘
阶乘:所有小于或等于该数的正整数的积
n的阶乘:n! = n * (n-1) * (n-2) *...* 3 * 2 * 1
分析:这与累和类似,只不过换成了乘法运算
代码实现
public class RecursionDemo03 {
public static void main(String[] args) {
int n = 6;
// 调用求阶乘的方法
int res = getValue(n);
// 输出结果
System.out.println(res);
}
/**
* 通过递归算法实现阶乘
* @param n 需要阶乘的最大值
* @return 返回n的阶乘
*/
private static int getValue(int n) {
// 1的阶乘为1
if (n == 1){
return 1;
}
// n不为1,调用getValue进行递归
return n * getValue(n-1);
}
}
运行结果
4.递归打印多级目录
分析:多级目录的打印,就是多级目录的嵌套,遍历之前无法知道具体有多少级目录,所以用递归代码实现
已有目录结构如下图所示的D盘A目录
代码实现
public class RecursionDemo04 {
public static void main(String[] args) {
// 创建File对象
File file = new File("D:\\A");
// 调用递归打印路径的方法
listMenu(file);
}
private static void listMenu(File file) {
// 先输出当前File
System.out.println(file);
// 获取子文件和子目录
File[] files = file.listFiles();
// 循环判断子文件和子目录
for (File chileFile : files) {
// 如果是子目录,递归打印路径
if (chileFile.isDirectory()){
listMenu(chileFile);
}else{
// 输出文件路径
System.out.println(chileFile);
}
}
}
}
运行结果