Java-递归思想

1 .递归:方法定义中调用方法本身的现象

误区

  • StringBuffer的对象.append().append().append() 这个不叫方法的递归,这个现象叫做方法的链式调用 Math.min(Min(a,b),c) 这个现象叫做方法嵌套调用,也不叫递归
            1、从前有座山,山里有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,讲的故事内容是:           1
                从前有座山,山里有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,讲的故事内容是:          2
                    从前有座山,山里有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,讲的故事内容是:      3
                        从前有座山,山里有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,讲的故事内容是:  4
                           ....
               以下情况,故事不在衍生:庙倒了,老和尚圆寂了。。

            2、学习大数据--高薪就业--挣钱--娶媳妇--生娃--挣钱学习大数据:
                学习大数据--高薪就业--挣钱--娶媳妇--生娃--挣钱学习大数据:
                    学习大数据--高薪就业--挣钱--娶媳妇--生娃--挣钱学习大数据:
                        学习大数据--高薪就业--挣钱--娶媳妇--生娃--挣钱学习大数据:
                            学习大数据--高薪就业--挣钱--娶媳妇--生娃--挣钱学习大数据:
                            ....
               娶不到媳妇,生不了娃。

递归注意事项:

  • 1、递归一定要有一个出口,结束条件,否则就是死递归
  • 2、递归的次数不能太多,否则就会造成栈内存溢出
  • 3、构造方法不能初始化
public class DiGuiDemo1 {
//    DiGuiDemo1(){
//        DiGuiDemo1();
//    }
    public static void show(int i){
        //要使用递归,必须要给出条件,否则就会无线循环下去。
        if(i < 0){
            System.out.println("结束循环!");
        }else{
            System.out.println(i);
            //递归调用本身, 先执行 --i 之后的结果在丢到 show 方法中
            show(--i);
        }
    }

    public static void main(String[] args) {
        //调用方法
            DiGuiDemo1.show(10);
    }
}

需求:求出 5 的阶乘

package com.shujia.wyh.day23;

/*
        需求:求出5的阶乘:
            5! = 5*4*3*2*1 = 120
               = 5*4!
               = 5*4*3!
               = 5*4*3*2!
               = 5*4*3*2*1!
 */
public class DiGuiDemo2 {
    public static void main(String[] args) {
        //在学习递归之前解决该问题的方式:
//        System.out.println(5*4*3*2*1);
        int result = 1;
        for (int i = 2; i <= 5; i++) {
            result = result * i;
        }
        System.out.println("5的阶乘为:" + result);
        System.out.println("===================================");
        //使用递归实现
        int i = jieCheng(5);
        System.out.println("5的阶乘为:" + i);


    }

    /*
            定义递归方法实现求阶乘
                1、结束条件:
                    if(i==1){return 1}

                2、递归的规律:
                    if(i!=1){
                        return i*jieCheng(i-1);
                    }
     */
    public static int jieCheng(int i) { // 5
        if (i == 1) {
            return 1;
        } else {
            //5 * jieCheng(4)
            //5 * 4 * jieCheng(3)
            //5 * 4 * 3 * jieCheng(2)
            //5 * 4 * 3 * 2 * jieCheng(1)
            return i * jieCheng(i - 1);
        }
    }
}

不死神兔问题:

package com.shujia.wyh.day23;

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

        寻找规律:
            月            对数
            1              1
            2              1
            3              2
            4              3
            5              5
            6              8
            7              13
            ...
       由此可见,兔子的对数数量:
       1,1,2,3,5,8,13,21,34....
       发现的规律是:
        1、从第三项开始,每一项都是前两项之和
        2、说明每一项的前两项数据是已知的


      如何实现:
        1、使用数组实现
        2、基本变量实现
        3、递归实现

 */
public class DiGuiDemo3 {
    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;
        //第6个相邻的数据: a=8,b=13;
        //...
        //规律:
        //下一次的相邻数据a是上一次相邻数据b的值,下一次相邻数据b是上一次a+b的值
        int a = 1;
        int b = 1;
        for (int i = 0; i < 18; i++) {
            //定义一个临时变量,保存上一次的a的值
            int temp = a;
            a = b;
            b = temp + b;
        }
        System.out.println("第20个月的时候,兔子对数为:" + b);
        System.out.println("=======================================");
        //使用递归实现
        int result = fibonacci(20);
        System.out.println("第20个月的时候,兔子对数为:" + result);
    }

    /*
        递归实现:
            1、结束条件是什么?
                当月份是1或者2的时候,return 1;
            2、递归的逻辑是:
                从第三个月到第20个月,每一个月是前两个月之和。
     */
    public static int fibonacci(int 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) + fibonacci(2) + fibonacci(2) + fibonacci(1)
            //1 + 1 + 1 + 1 + 1 = 5
            return fibonacci(month - 1) + fibonacci(month - 2);
        }
    }
}

遍历递归文件名

package com.shujia.wyh.day23;
import java.io.File;
/*
    递归遍历D:\IdeaProjects\bigdata17\src\com\shujia\wyh目录下指定后缀名.jpg结尾的文件名称
 */
public class DiGuiDemo4 {
    public static void main(String[] args) {
        File file = new File("D:\\IdeaProjects\\bigdata17\\src\\com\\shujia\\wyh");

        //定义一个递归方法实现
        getJpgFile(file);
    }

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

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


    }
}

递归删除带内容的目录


import java.io.File;
import java.io.FileFilter;

/*
        递归删除带内容的目录
 */
public class DiGuiDemo5 {
    public static void main(String[] args) {
//        File file = new File("D:\\aaaa");
//        File[] files = file.listFiles();
////        System.out.println(files);
//        System.out.println(files.length);

        File file = new File("D:\\aaaa");

        deleteFile(file);
    }

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

        //判断这个数组是不是空,如果是空的,就直接删除
        if (files.length != 0) {
            //遍历数组
            for(File f : files){
                //判断是否是文件夹
                if(f.isDirectory()){
                    deleteFile(f);
                }else {
                    //不是文件夹的时候,可以直接删除
                    System.out.println(f.getName() + ":" + f.delete());
                }
            }
            System.out.println(file.getName() + ":" + file.delete());
        } else {
            System.out.println(file.getName() + ":" + file.delete());
        }

    }
}

posted @ 2022-04-08 08:41  a-tao必须奥利给  阅读(59)  评论(0编辑  收藏  举报