1 概述
递归:指在当前方法内调用自己的这种现象。
递归的分类:
- 递归分为两种,直接递归和间接递归。
- 直接递归称为方法自身调用自己。
- 间接递归可以A方法调用B方法,B方法调用C方法,C方法调用A方法。
注意事项:
- 递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。
- 在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。
- 构造方法,禁止递归
递归的使用前提:
当调用方法的时候,方法的主题不变,每次调用方法的参数不同,可以使用递归
代码如下:
public class Recurison01 {
public static void main(String[] args) {
//a();
//b(1);
//Recurison01();
}
/*
构造方法,禁止递归
编译报错:构造方法是创建对象使用的,一直递归会导致内存中有无数个对象,直接编译报错
*/
public Recurison01(){
// Recurison01();
}
/*
在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。
11268 Exception in thread "main" java.lang.StackOverflowError
*/
private static void b(int a) {
System.out.println(a);
if (a==20000){
return;
}
b(++a);
}
/*
递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。
Exception in thread "main" java.lang.StackOverflowError
a方法会在栈内存中一直调用a方法,就会导致栈内存中有无数个a方法,超出了
栈内存的大小,就会导致内存溢出的错误。
注意:当一个方法调用其他方法的时候,被调用的方法没有执行完毕,当前方法会
一直等待调用的方法执行完毕,才会继续执行。
*/
private static void a() {
System.out.println("okc okc");
a();
}
}
2 递归累加求和
计算1 ~ n的和
分析:num的累和 = num + (num-1)的累和,所以可以把累和的操作定义成一个方法,递归调用。
代码如下:
public class Recurison02 {
public static void main(String[] args) {
int sum = method01(5);
System.out.println(sum);
}
private static int method01(int i) {
if (i==1){
return 1;
}
return i+method01(--i);
}
}
使用递归求和,main方法调用sum方法,sum方法会一直调用sum方法
导致在内存中有多个sum方法(频繁的创建方法,调用方法,销毁方法)效率低下.
如果仅仅计算1-n之间的和,建议使用for循环
3 递归求阶乘
- 阶乘:所有小于及等于该数的正整数的积。
n的阶乘:n! = n * (n-1) *...* 3 * 2 * 1
分析:这与累和类似,只不过换成了乘法运算,需要注意阶乘值符合int类型的范围。
推理得出:n! = n * (n-1)!
代码示例:
public class Recurison02 {
public static void main(String[] args) {
int fac = method02(6);
System.out.println(fac);
}
private static int method02(int a) {
if (a==1){
return 1;
}
return a*method02(--a);
}
4 递归打印多级目录
分析:多级目录的打印,就是当目录的嵌套。遍历之前,无从知道有多少级目录,所以要使用递归实现。
代码示例:
import java.io.File;
/*
递归打印多级目录
*/
public class Recurison03 {
public static void main(String[] args) {
File file=new File("D:\\图片");
getAllFile(file);
}
/*
定义一个方法,参数传递File类型的目录
方法中对目录进行遍历
*/
private static void getAllFile(File dir) {
File[] files = dir.listFiles();
for (File f : files) {
//对遍历得到的File对象进行判断,判断是否是文件夹
if (f.isDirectory()){
/*f是文件夹,则继续遍历这个文件夹。getAllFile方法就是传递文件夹、遍历文件夹的方法
所以直接调用getAllFile方法即可:递归(自己调用自己)*/
getAllFile(f);
}else{
System.out.println(f);
}
}
}
}
运行结果:
版权声明:本文为weixin_44649793原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。