递归:指在当前方法内调用本身的现象。算法
递归的分类:ui
注意:spa
递归致使栈内存溢出的原理:3d
计算 1~ n 的和,n 的累加 = n + (n+1) 的累和,能够把累和的操做定义成一个方法,递归调用。code
实现:对象
1 public class Demo { 2 public static void main(String[] args) { 3 //计算1~num的和,使用递归完成 4 int num = 5; 5 // 调用求和的方法 6 int sum = getSum(num); 7 // 输出结果 8 System.out.println(sum); 9 } 10 /* 11 经过递归算法实现. 12 参数列表:int 13 返回值类型: int 14 */ 15 public static int getSum(int num) { 16 /* 17 num为1时,方法返回1, 18 至关因而方法的出口,num总有是1的状况 19 */ 20 if(num == 1){ 21 return 1; 22 } 23 /* 24 num不为1时,方法返回 num +(num‐1)的累和 25 递归调用getSum方法 26 */ 27 return num + getSum(num‐1); 28 } 29 }
代码执行图解:blog
注意:递归必定要有条件限定,保证递归可以中止下来,次数不要太多,不然会发生栈内存溢出。
递归
阶乘:全部小于及等于该数的正整数的积。内存
分析:n! = n * (n-1);get
实现:
1 public class DiGuiDemo { 2 //计算n的阶乘,使用递归完成 3 public static void main(String[] args) { 4 int n = 3; 5 // 调用求阶乘的方法 6 int value = getValue(n); 7 // 输出结果 8 System.out.println("阶乘为:"+ value); 9 } 10 /* 11 经过递归算法实现. 12 参数列表:int 13 返回值类型: int 14 */ 15 public static int getValue(int n) { 16 // 1的阶乘为1 17 if (n == 1) { 18 return 1; 19 } 20 /* 21 n不为1时,方法返回 n! = n*(n‐1)! 22 递归调用getValue方法 23 */ 24 return n * getValue(n ‐ 1); 25 } 26 }
问题:第一我的10,第2个比第1我的大2岁,以此类推,请用递归方式计算出第8我的多大?
实现:
1 public int getAge(int n){ 2 /* 3 * 第一我的10,n=1, 结果10 4 * 第二我的12,n=2, 结果10 + 2 getAge(1) + 2 5 * 第三我的14,n=3, 结果10 + 2 + 2 getAge(2) + 2 6 * 7 * 第n我的?,n=?, 结果10 + 2 + 2 ...+ ? getAge(n-1) + 2 8 */ 9 if(n==1){ 10 return 10; 11 }else{ 12 return getAge(n-1) + 2; 13 } 14 }
问题:有n步台阶,一次只能上1步或2步,共有多少种走法?
实现:
1 public long sum(int n){ 2 /* 3 * n==1 1 4 * n==2 2 5 * n==3 最后一步 要么从第1级跨2步,要么从第2级跨1步 把走到第1级的走法 + 走到第2级的走法 sum(1) + sum(2) 6 * n==4 最后一步 要么从第2级跨2步,要么从第3级跨1步 把走到第2级的走法 + 走到第3级的走法 sum(2) + sum(3) 7 * n==5 最后一步 要么从第3级跨2步,要么从第4级跨1步 把走到第3级的走法 + 走到第4级的走法 sum(3) + sum(4) 8 * 9 * n=? 最后一步 要么从第n-2级跨2步,要么从第n-1级跨1步 把走到第n-2级的走法 + 走到第n-1级的走法 sum(n-2) + sum(n-1) 10 */ 11 if(n==1 || n==2){ 12 return n; 13 }else{ 14 return sum(n-1) + sum(n-2); 15 } 16 }
分析:多级目录的打印,就是当目录的嵌套。遍历以前,无从知道到底有多少级目录,因此咱们仍是要使用递归实现。
实现1:
1 public class DiGuiDemo { 2 public static void main(String[] args) { 3 // 建立File对象 4 File dir = new File("D:\\aaa"); 5 // 调用打印目录方法 6 printDir(dir); 7 } 8 public static void printDir(File dir) { 9 // 获取子文件和目录 10 File[] files = dir.listFiles(); 11 // 循环打印 12 /* 13 判断: 14 当是文件时,打印绝对路径. 15 当是目录时,继续调用打印目录的方法,造成递归调用. 16 */ 17 for (File file : files) { 18 // 判断 19 if (file.isFile()) { 20 // 是文件,输出文件绝对路径 21 System.out.println("文件名:"+ file.getAbsolutePath()); 22 } else { 23 // 是目录,输出目录绝对路径 24 System.out.println("目录:"+file.getAbsolutePath()); 25 // 继续遍历,调用printDir,造成递归 26 printDir(file); 27 } 28 } 29 } 30 }
实现2:
1 //listAllSub()方法的功能是列出一个文件或一个目录及它的下一级 2 public void listAllSub(File dir){ 3 if(dir.isDirectory()){ 4 File[] listFiles = dir.listFiles(); 5 for (File sub : listFiles) {//sub多是一个文件,也多是一个文件夹 6 listAllSub(sub);//递归:本身调用本身 7 } 8 } 9 System.out.println(dir); 10 }
实现:
1 public long getLength(File dir){ 2 if (dir != null && dir.isDirectory()) { 3 File[] listFiles = dir.listFiles(); 4 if(listFiles!=null){ 5 long sum = 0; 6 for (File sub : listFiles) { 7 sum += getLength(sub); 8 } 9 return sum; 10 } 11 }else if(dir != null && dir.isFile()){ 12 return dir.length(); 13 } 14 return 0; 15 }
实现:
1 public void deleteDir(File file){ 2 //若是是文件夹,先把它的下一级删除 3 if(file.isDirectory()){ 4 File[] listFiles = file.listFiles(); 5 //通过这个foreach循环,能够把file的全部的下一级删除 6 for (File sub : listFiles) { 7 deleteDir(sub); 8 } 9 } 10 11 //文件夹就变成了空文件夹,就能够直接删 12 //若是是文件也能够直接删除 13 file.delete(); 14 }