递归的概念
递归就是方法自己调用自己,每次调用时传入不同的变量,递归有助于编程者解决复杂的问题,同时可以让代码变得简洁。
- 递归的分类:
- 递归分为两种,直接递归和间接递归。
- 直接递归称为方法自身调用自己。
- 间接递归可以A方法调用B方法,B方法调用C方法,C方法调用A方法。
- 注意事项:
- 递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。
- 在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。
- 构造方法,禁止递归
public class DiGuiDemo2 {
public static void main(String[] args) {
// 创建File对象
File dir = new File("D:\\aaa");
// 调用打印目录方法
printDir(dir);
}
public static void printDir(File dir) {
// 获取子文件和目录
File[] files = dir.listFiles();
// 循环打印
/*
判断:
当是文件时,打印绝对路径.
当是目录时,继续调用打印目录的方法,形成递归调用.
*/
for (File file : files) {
// 判断
if (file.isFile()) {
// 是文件,输出文件绝对路径
System.out.println("文件名:"+ file.getAbsolutePath());
} else {
// 是目录,输出目录绝对路径
System.out.println("目录:"+file.getAbsolutePath());
// 继续遍历,调用printDir,形成递归
printDir(file);
}
}
}
}
递归遍历文件夹及文件并指定后缀输出
package com.snail.test.io;
import java.io.File;
public class Demo1 {
public static void main(String[] args) {
File file = new File("/Users/snail/Documents/note");
getAllFile(file);
}
private static void getAllFile(File dir) {
File[] files = dir.listFiles();
for (File file : files) {
if(file.isDirectory()){
getAllFile(file);
}else{
if(file.getName().toLowerCase().endsWith(".txt")){
System.out.println(file);
}
}
}
}
}
递归删除指定目录下的所有文件目录
public static void delFile(File file){
if(file.isDirectory()){
File[] files = file.listFiles();
for(File f : files){
if(f.isFile()){
f.delete();
}else if(f.isDirectory()){
delFile(f)
}
}
}
}
测试代码
package top.snailstudy.recursion;
public class RecursionTest {
public static void main(String[] args) {
test(4);
}
public static void test(int n){
if(n > 2){
test(n -1);
}
System.out.println("n="+n);
}
}
分析图
阶乘实例
package top.snailstudy.recursion;
public class RecursionTest {
public static void main(String[] args) {
int i = factorial(6);
System.out.println(i); //输出 720
}
public static int factorial(int n){
if(n==1){
return 1;
}else {
return factorial(n-1)*n;
}
}
}
递归能解决什么样的问题?
- 各种数学问题如:8皇后问题,汉若塔,阶乘问题,迷宫问题,球和篮子的问题...
- 各种算法中也会使用到递归,比如快排,归并排序,二分查找,分治算法等
- 将用栈解决的问题,可以用递归解决代码更简洁
递归需要遵循的重要规则
- 执行一个方法时,就创建一个新的受保护的独立空间(栈空间)
- 方法的局部变量是独立的,不会相互影响
- 如果方法中使用的是引用类型变量,就会共享该引用类型的数据
- 递归必须向退出递归的条件逼近,否则就是无限死循环
- 当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕。