遞歸的分類: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文件
分析:
目錄搜索,沒法判斷有多少級目錄,因此使用遞歸,遍歷全部的目錄
遍歷目錄的時候,獲取的是全部的子文件
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); } } } }