遞歸

遞歸

 概述

  遞歸:指的是當前方法調用本身是一種現象。
  • 遞歸的分類:java

  •     遞歸分爲兩類:之間遞歸和間接遞歸ide

  •     直接遞歸:稱爲方法自身調用本身的狀況優化

  •     間接遞歸:能夠歸結爲:方法A調用了方法B,方法B調用了方法C,方法C反過來又調用了方法A。code

- 注意事項:

  •   遞歸必定要有邊界條件(條件限定) ,保證遞歸可以中止下來,不然會發生棧內存溢出。對象

  •   在遞歸當中雖然有限定條件,可是遞歸的次數也不能太多,不然也會發生棧內存溢出現象。遞歸

  •   構造方法禁止遞歸。內存

示例代碼:get

public class Demo01Recursion{
	public static void main(String[] args){
        sum(1);
        int i = sum02(20000);
        System.out.println(i);
    }
}

	/*
       定義一個方法,求和的方法
       對於遞歸雖然有邊界條件,可是遞歸的次數不能太多,不然依然會拋出棧內存溢出錯誤。
     */
	public static int sum02(int n){
        Syatem.out.println(n);
        if(n==1){
            return 1;
        }
        return n+sum02(n-1);    
    }
	/* 1+ 2 + 3 + 4 + 5 + ..... + n
       n+ n-1 + n-2 + n-3 + .... + 1
        定義求和的方法
      Exception in thread "main" java.lang.StackOverflowError
      遞歸必定要有邊界條件,保證遞歸可以中止下來。
     */
	public static int sum(int n){
    	System.out.println("當前n的值爲:"+n);
    	return n+sum(n-1);
	}
}

使用遞歸實現累加和

計算1~n的和it

分析:1+2+3+4+5+6+7+...+n--->n+(n-1)+(n-2)+(n-3)+(n-4)+...+(n-n-1);io

public class Demo02Recursion {
    public static void main(String[] args) {
        int sum = sum(10);
        System.out.println(sum);

    }
    public  static int sum(int n){
        //邊界條件
        if (n==1){
            return 1;
        }
        //獲取下一個被加的數字
        return n+sum(n-1);
    }
}

遞歸求階乘

  • 階乘:全部小於及等於該數的正整數的乘積。

n的階乘: n!=n(n-1) (n-2)* (n-3)....321

代碼示例:

public class Demo02Recursion {
    public static void main(String[] args) {
        int sum = sum(10);
        System.out.println(sum);

    }
    public  static int sum(int n){
        //邊界條件
        if (n==1){
            return 1;
        }
        //獲取下一個被加的數字
        return n*sum(n-1);
    }
}

使用遞歸打印多級目錄

public class Demo04Recursion {

    public static void main(String[] args) {
        // 找到Hello文件的路徑
        File file = new File("C:\\Users\\admin\\Desktop\\Hello");
        //調用getAllFiles()
        getAllFiles(file);
    }

    /*
        定義一個方法,參數傳遞File類型的目錄
        方法中要對目錄進行遍歷
     */
    public static void getAllFiles(File file) {
        // 代表file此時是一個目錄
        System.out.println(file);
        //首先先獲取到它直接子目錄和直接子文件
        File[] files = file.listFiles();
        // 遍歷files目錄
        for (File f : files) {
            // 判斷若是獲得的f是一個目錄,須要再次遍歷
            if (f.isDirectory()) {
                // 代表f是一個目錄,則繼續遍歷這個目錄
                //getAllFiles方法就是獲取全部的文件,參數傳遞的恰好是目錄。因此直接調用getAllFiles:遞歸(本身調用本身)
                getAllFiles(f);
               /* File[] files1 = f.listFiles();
                for (File file1 : files1) {
                }*/
            } else {
                // 此時f不是一個目錄,確定是一個文件
                System.out.println(f);
            }
        }
    }
}

綜合案例

文件搜索

搜索: C:Users\admin\DesktoplHello目錄中的全部的.txt文件

分析:

  1. 目錄搜索,沒法判斷有多少級目錄,因此使用遞歸,遍歷全部的目錄

  2. 遍歷目錄的時候,獲取的是全部的子文件

public class FileFilterImpl implements FileFilter {
        /*
            過濾的規則:
                在accept方法中,判斷File類對象是否以.txt結尾
                是就返回true
                不是就返回false
                若是此File對象是一個文件夾,則返回true,繼續遍歷這個文件夾
         */
        @Override
        public boolean accept(File pathname) {
            if (pathname.isDirectory()) {
                return true;
            }
            return pathname.getName()
                    .toLowerCase()
                    .endsWith(".txt");
        }
}
public class Demo07Recursion {

    public static void main(String[] args) {
        //構建一個File對象獲得C:\Users\admin\Desktop\Hello路徑
        File file = new File("C:\\Users\\admin\\Desktop\\Hello");
        getAllTxt(file);
    }

    /*
        定義一個方法,遍歷全部的.txt文件
        方法中依然須要傳參數目錄
     */
    public static void getAllTxt(File dir) {
        //匿名內部類的寫法
        File[] files = dir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {

                if (pathname.isDirectory()) {
                    return true;
                }
                return pathname.getName().toLowerCase().endsWith(".txt");
            }
        });

        // 使用FilenameFilter
        File[] files = dir.listFiles(new FilenameFilter() {

            @Override
            public boolean accept(File dir, String name) {
                if (pathname.isDirectory()) {
                    return true;
                }
                return pathname.getName().toLowerCase().endsWith(".txt");
              
            }

        });

       File[] files = dir.listFiles((File d, String name) -> {
            return new File(d,name).isDirectory() || name.toLowerCase().endsWith(".txt");
        });
        File[] files = dir.listFiles((d,name)  -> new File(d,name).isDirectory() || name.toLowerCase().endsWith(".txt"));

        // 使用Lambda表達式優化
        File[] files = dir.listFiles((File pathname) -> {
            return pathname.getName().toLowerCase().endsWith(".txt") || pathname.isDirectory();
        });

        // 能夠再次優化下代碼
        File[] files = dir.listFiles(pathname ->pathname.getName().toLowerCase().endsWith(".txt") || pathname.isDirectory());



        /*
                C:\Users\admin\Desktop\Hello\aa\123.txt
                C:\Users\admin\Desktop\Hello\bb\bb.txt
                C:\Users\admin\Desktop\Hello\cc\cc.txt
                C:\Users\admin\Desktop\Hello\hello (2).TXT
                C:\Users\admin\Desktop\Hello\hello.txt
         */
        //遍歷files
        for (File f : files) {
            // 判斷f是不是一個目錄
            if (f.isDirectory()) {
                getAllTxt(f);
            } else {
                // 先獲取文件的名稱
                System.out.println(f);
            }
        }
    }
}
相關文章
相關標籤/搜索