递归-基础

1.递归的概述

递归:方法自己调用自己

递归的分类:

1.直接递归

public void a(){
    a();
}

2.间接递归

public void a(){
    b();
}

public void b(){
    a();
}

递归的注意事项:

  • 递归必须有结束的条件,保证递归可以停止下来,否则会抛出内存溢出的错误
  • 递归有结束的条件,但是递归的次数也不能太多,否则会抛出内存溢出的错误
  • 构造方法禁止递归

什么时候使用递归:

​ 当我们频繁的调用一个方法,方法的主体不变,每次调用方法的参数改变,就可以使用递归

public class Demo01Recursion {
    public static void main(String[] args) {
        //a();
        b(1);
    }

    /*
        3.构造方法禁止递归
            构造方法是创建对象使用的,递归调用自己,会在内存中一直创建对象,停不下来
     */
    public Demo01Recursion() {
        //Demo01Recursion();
    }

    /*
        2.递归有结束的条件,但是递归的次数也不能太多,否则会抛出内存溢出的错误
        11418,11406 内存使用频率是随时变化的,得到的结果不一样
            Exception in thread "main" java.lang.*Error
     */
    private static void b(int i) {//i=1,2,3,4...
        System.out.println(i);
        if(i==20000){
            return;//结束方法,不在继续调用了
        }
        b(++i);
    }

    /*
        1.递归必须有结束的条件,保证递归可以停止下来,否则会抛出内存溢出的错误
        Exception in thread "main" java.lang.*Error
     */
    private static void a() {
        System.out.println("a方法!");
        a();
    }
}

递归-基础

2.练习:使用递归计算1-n的和

/*
    练习:使用递归计算1-n的和
    递归就是方法自己调用自己,只要我们使用递归,就需要定义一个方法,自己调用自己求和
 */
public class Demo02Recursion {
    public static void main(String[] args) {
        int s = sum(20000);
        System.out.println(s);
    }

    /*
        定义一个计算1-n和的方法
        1-n的和就是n-1的和
        n+(n-1)+(n-2)+(n-3)+...+1
        已知:
            n:10,100,1000,...
            加到1结束
        未知:
            n-1
        递归的目的:获取下一个被加的数字n-1
        递归结束的条件:获取n-1==1的时候,结束递归
     */
    public static int sum(int n){
        //递归结束的条件:获取n-1==1的时候,结束递归
        if(n==1){
            return 1;
        }
        //递归的目的:获取下一个被加的数字n-1
        return n + sum(n-1);
    }
}

递归-基础

3.练习:递归求阶乘

package com.itheima.demo02Recursion;

/*
    练习:递归求阶乘(重点)
        n的阶乘: n!=n*(n-1)*(n-2)*...*1;
        5!= 5*4*3*2*1;
 */
public class Demo03Recursion {
    public static void main(String[] args) {
        int i = jieCheng(5);
        System.out.println(i);
    }

    /*
        定义一个计算阶乘的方法
        已知:
            n:5,6,7,8,9...
            乘到1结束
        未知:
            n-1
        递归的目的:获取下一个被乘的数字n-1
        递归的结束条件:获取n-1==1的时候结束
     */
    public static int jieCheng(int n){//5,4,3,2,1
        //递归的结束条件:获取n-1==1的时候结束
        if(n==1){
            return 1;
        }
        //递归的目的:获取下一个被乘的数字n-1
        return n*jieCheng(n-1);
    }
}

4.练习:使用递归遍历文件夹和文件夹中的子文件夹

递归-基础

package com.itheima.demo02Recursion;

import java.io.File;

/*
    练习:使用递归遍历文件夹和文件夹中的子文件夹(遍历多级文件夹)
    遍历d:\\aaa目录
    d:\\aaa
    d:\\aaa\\aaa.java
    d:\\aaa\\aaa.txt
    d:\\aaa\\全球通史.txt
    d:\\aaa\\a
    d:\\aaa\\a\\a.java
    d:\\aaa\\a\\a.jpg
    d:\\aaa\\b
    d:\\aaa\\b\\b.avi
    d:\\aaa\\b\\B.JAVA
 */
public class Demo04Recursion {
    public static void main(String[] args) {
        File file = new File("d:\\aaa");
        getAllFile(file);
    }

    /*
        定义一个方法,参数传递要遍历的文件夹File对象
        在方法内部对文件夹进行遍历
     */
    public static void getAllFile(File dir){
        System.out.println(dir);//打印要遍历的文件夹名称
        File[] files = dir.listFiles();
        for (File f : files) {
            //判断遍历得到的文件对象f,是否是一个文件夹
            if(f.isDirectory()){
                //f是一个文件夹,继续遍历这个文件夹
                //我们发现getAllFile方法,就是一个传递文件夹,遍历文件夹的方法
                //调用getAllFile方法即可,传递要遍历的文件夹(f==a|f==b)
                getAllFile(f);//方法中自己调用自己==>递归
            }else{
                //f就是一个文件,打印==>f.toString()方法
                System.out.println(f);
            }
        }
    }
}

5.练习:文件搜索

package com.itheima.demo02Recursion;

import java.io.File;

/*
    练习:文件搜索
    遍历d:\\aaa目录,只打印以.java(.JAVA)结尾的文件,不分区大小写
    d:\\aaa
    d:\\aaa\\aaa.java
    d:\\aaa\\aaa.txt
    d:\\aaa\\全球通史.txt
    d:\\aaa\\a
    d:\\aaa\\a\\a.java
    d:\\aaa\\a\\a.jpg
    d:\\aaa\\b
    d:\\aaa\\b\\b.avi
    d:\\aaa\\b\\B.JAVA
 */
public class Demo05Recursion {
    public static void main(String[] args) {
        File file = new File("d:\\aaa");
        getAllFile(file);
    }

    /*
        定义一个方法,参数传递要遍历的文件夹File对象
        在方法内部对文件夹进行遍历
     */
    public static void getAllFile(File dir){
        File[] files = dir.listFiles();
        for (File f : files) {
            //判断遍历得到的文件对象f,是否是一个文件夹
            if(f.isDirectory()){
                //f是一个文件夹,继续遍历这个文件夹
                getAllFile(f);//方法中自己调用自己==>递归
            }else{
                /*
                    f就是一个文件,打印==>f.toString()方法
                    需求:只打印以.java(.JAVA)结尾的文件,不分区大小写
                    解决:
                        判断f是不是一个以.java(.JAVA)结尾的文件,是则打印
                    实现步骤:
                        1.把f对象(File对象)转换为String
                            a==>f.toString() "d:\\aaa\\aaa.java"
                            b==>f.getPath() "d:\\aaa\\aaa.java"
                            c==>f.getName() "aaa.java"
                        2.使用String类的方法endsWith判断字符串是否以.java结尾
                        3.是.java结尾的文件则打印
                 */
                /*String name = f.getName();
                name = name.toLowerCase();
                boolean b = name.endsWith(".java");
                if(b){
                    System.out.println(f);
                }*/
                if(f.getName().toLowerCase().endsWith(".java")){
                    System.out.println(f);
                }
            }
        }
    }
}

上一篇:aaa


下一篇:Mysql的外键约束、内外连接查询以及锁