IO--递归

递归的概述及注意事项

/*

        递归:
            方法定义本身调用方法本身的现象叫做递归

        StringBuffer.append().append().append() 这个不叫递归,这个叫方法的连续调用
        Math.max(Math.max(a,b),c)  这个也不叫递归,这个叫方法的嵌套使用

         递归的注意事项:
            1、递归一定要有一个出口,结束条件,否则就是死循环
            2、递归的次数不能太多,否则就会发生内存溢出
            3、构造方法不能使用递归

*/

public class RecursionDemo1 {
  
     //构造方法不能使用递归
//     RecursionDemo1(){
//         RecursionDemo1();
//     }

    public static void show(int i){
        //第一步:定义结束条件
        if(i<0){
            System.out.println("结束递归");
        }else {
            System.out.println(i);
            //不能是 i--
            //因为 i-- 都是先赋值再 --
            //那么i永远都是10
            show(--i);
        }
    }

    public static void main(String[] args) {
        show(10);
    }
}

递归内存图

递归思想的应用

/*
        递归求阶乘:
            5!= 5*4*3*2*1 = 120
               = 5*4!
               = 5*4*3!
               = 5*4*3*2!
               = 5*4*3*2*1!
*/

public class RecursionDemo2 {
    public static void main(String[] args) {
      
        //在学习递归之前的做法:
        int result = 1;

        for (int x = 2; x <= 5; x++) {
            result = result * x;
        }
        System.out.println("5的阶乘是:" + result);
      
        System.out.println("====================");
      
        //学习递归之后
        System.out.println("5的阶乘是:" + recursionFun(5));

    }
    /*
            递归的实现思想:
                1、结束条件:
                    if(i==1){return 1}

                2、寻找规律:
                    if(i!=1){
                        return i * recursionFun(i-1);
                    }
    */
    public static int recursionFun(int i) {
        if(i==1){
            return 1;
        }else {
            //5 * recursionFun(4)
            //5 * 4 * recursionFun(3)
            //5 * 4 * 3 * recursionFun(2)
            //5 * 4 * 3 * 2 * recursionFun(1)
            //5 * 4 * 3 * 2 * 1
            return i * recursionFun(i-1);
        }
    }
}
/*

        兔子问题(斐波那契数列)
            有一对兔子,从出生第三个月开始,每个月都生一对兔子,
            小兔子长到三个月后每个月又生一对兔子,假设这些兔子都不会死,
            问:20个月,又多少对兔子?

        找规律:
            月         兔子对数
            1             1
            2             1
            3             2
            4             3
            5             5
            6             8
            7             13
            ...

       由此可见,兔子的对数数量是:
       1、1、2、3、5、8、13、21...

       发现的规律是:
            1、从第三项开始,每一项都是前两项之和
            2、说明每一项的前两项的数据是已知的

       如何实现呢?
            1、数组方式实现
            2、基本变量实现
            3、递归方式实现

*/

public class RecursionDemo3 {
    public static void main(String[] args) {
      
        //第一种方式:使用数组实现
      
        int[] arr = new int[20];
        arr[0] = 1;
        arr[1] = 1;
      
//        arr[2] = arr[0]+arr[1];
//        arr[3] = arr[1]+arr[2];
//        arr[4] = arr[2]+arr[3];
//        //...
//        arr[19] = arr[17] + arr[18];
      
        for (int i = 2; i < arr.length; i++) {
            arr[i] = arr[i - 2] + arr[i - 1];
        }
        System.out.println("第20个月的兔子对数为:" + arr[19]);
      
        System.out.println("====================================");

        //第二种方式:基本变量
      
        //定义两个变量表示相邻的两项
        //第1个相邻的数据:a=1,b=1;
        //第2个相邻的数据:a=1,b=2;
        //第3个相邻的数据:a=2,b=3;
        //第4个相邻的数据:a=3,b=5;
        //第5个相邻的数据:a=5,b=8;
        //...
        //规律:
        //下一次的相邻数据a是上一次相邻数据的b的值,下一次相邻数据的b是上一次的a+b的值
      
        int a = 1;
        int b = 1;
        //第1和第2个月的兔子对数给出来了
        //剩下的18个月中有17个相邻的
        for (int i = 0; i < 18; i++) {
            //定义一个临时变量,保存上一次a的值
            int temp = a;
            a = b;
            b = temp + b;
        }
        System.out.println("第20个月的兔子对数为:" + b);
      
        System.out.println("======================================");
      
        //第三种方式:递归方式实现
      
        System.out.println("第20个月的兔子对数为:" + fibonacci(20));
    }

    /*
        递归实现:
            1、结束条件是什么?
                当month的值是1或者2的时候,return 1;
            2、递归的逻辑:
                从month==3到month==20的时候,每一个月都是前两个月之和
    */
    public static int fibonacci(int month){ //如果month=5
        if(month==1 ||month==2){
            return 1;
        }else {
            //fibonacci(4) + fibonacci(3)
            //fibonacci(3) + fibonacci(2) + fibonacci(2) + fibonacci(1)
            //fibonacci(2) + fibonacci(1) + 1 + 1 + 1
            //1 + 1 + 1 + 1 + 1
            //5
            return fibonacci(month-1) + fibonacci(month-2);
        }
    }
}
import java.io.File;

/*
    递归遍历目录下指定后缀名结尾的文件名称E:\数加科技\十四期所有.png结尾的文件名称
*/

public class RecursionDemo4 {
    public static void main(String[] args) {
        //将该目录封装成一个File对象
        File file = new File("E:\\数加科技\\十四期");
        //定义一个方法实现递归
        getPngFile(file);
    }

    public static void getPngFile(File file){
      
        //获取该目录下所有的file对象数组
        File[] files = file.listFiles();

        //遍历数组得到每一个File对象
        for(File f:files){
            //判断该File对象是否是一个文件夹
            if(f.isDirectory()){
                getPngFile(f);
            }else {
                //判断文件的名称是否以.png后缀
                if(f.getName().endsWith(".png")){
                    //是,就输出
                    System.out.println(f.getName());
                }
            }
        }
    }
}
import java.io.File;

/*
    递归删除带内容的目录E:\数加科技\十四期副本
*/

public class RecursionDemo5 {
    public static void main(String[] args) {
        File file = new File("E:\\数加科技\\十四期副本");

        //定义方法实现递归
        deleteFileFun(file);
    }

    public static void deleteFileFun(File file) {
        //获取该目录下所有的file对象组成的数组
        File[] files = file.listFiles();

        //判断该数组是不是空,如果是空直接删除
        if (files != null) {
            //遍历数组,得到每一个File对象
            for(File f:files){
                //判断是否是文件夹
                if(f.isDirectory()){
                    deleteFileFun(f);
                }else {
                    //不是文件夹的时候,直接删除
                    System.out.println(f.getName()+": "+f.delete());
                }
            }
            //如果在执行完上面的步骤之后十四期副本里面内容为空,就删除十四期副本。
            System.out.println(file.getName()+": "+file.delete());
        }else {
            //如果走if判断时十四期副本为空,则直接删除十四期副本
            System.out.println(file.getName()+": "+file.delete());
        }
    }
}
posted @ 2021-12-25 22:15  赤兔胭脂小吕布  阅读(42)  评论(0编辑  收藏  举报