递归经典题
递归思想:方法自己调用自己,使用是要避免堆栈溢出 java.lang.StackOverflowError
递归步骤:
递推:将复杂的问题,变成简单问题,最后到一个最简单的状态,此时有一个已知值(追本溯源)
回归:再从已知值,从简单状态算到复杂状态
递归优点,思想简单;递归缺点,效率低
1.斐波那契数列
斐波那契数,亦称之为斐波那契数列(意大利语: Successione di Fibonacci),又称黄金分割数列、费波那西数列、费波拿契数、费氏数列,指的是这样一个数列:1、1、2、3、5、8、13、21、……在数学上,斐波那契数列以如下被以递归的方法定义:F0=0,F1=1,Fn=Fn-1+Fn-2(n>=2,n∈N*),用文字来说,就是斐波那契数列由 0 和 1 开始,之后的斐波那契数列系数就由之前的两数相加。
1 public class FibonacciNumbers { 2 public static void main(String[] args) { 3 // 1,1,2,3,5,8,13 4 System.out.println(getNum(2)); 5 System.out.println(getNum(5)); 6 System.out.println(getNum(6)); 7 8 } 9 10 static int getNum(int index) { 11 int num = -1; 12 if (index == 1 || index == 2) { 13 num = 1; 14 } else { 15 return getNum(index - 1) + getNum(index - 2); 16 } 17 return num; 18 } 19 20 } 21 //执行结果 22 //1 23 //5 24 //8
2.递归遍历目录
遍历思想,我们通过files.listFiles()
public File[] listFiles()
- 返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件,意思是数组元素是每个文件的抽象路径名,可能是文件可能是数组,此时就需要判断该路径的文件是目录还是文件,如果是文件,直接输出,如果是目录,我们就再次调用方法得到该目录下路径名文件的数组,然后判断。
1 import java.io.File; 2 3 public class Recursion { 4 void fileRecursion(String path) { 5 File files = new File(path); 6 File[] listFiles = null; 7 //因为系统的有些文件我们是没有权限访问的,但我们也能得到一个空的文件数组,这里判断是否为空的目的就是避免出现NullPointerException 8 if ((listFiles = files.listFiles()) != null) { 9 for (File list : listFiles) { 10 //判断文件f是否为文件夹形式 11 if (!list.isDirectory()) { 12 System.out.println(list.getAbsolutePath()); 13 } 14 Recursion name = new Recursion(); 15 // 不是文件就是目录,我们将目录路径给本方法,这就是递归 16 name.fileRecursion(list.getAbsolutePath()); 17 } 18 } 19 } 20 21 public static void main(String[] args) { 22 Recursion name = new Recursion(); 23 name.fileRecursion("C:\\System Volume Information"); 24 } 25 26 }
3.汉诺塔
汉诺塔问题是一个经典的问题。汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,任何时候,在小圆盘上都不能放大圆盘,且在三根柱子之间一次只能移动一个圆盘。问应该如何操作?
1 import java.io.File; 2 3 public class Demo02 { 4 5 static int i=1; 6 7 public static void main(String[] args) { 8 //getAllFiles("C:\\Windows"); 9 move("A","B","C",10); //2^n-1 10 } 11 12 public static void move(String source ,String help ,String target,int n) { 13 if(n==1) { 14 System.out.println(source+"--->"+target); 15 }else { 16 move(source,target,help,n-1); 17 System.out.println(source+"--->"+target); 18 move(help,source,target,n-1); 19 } 20 }