在算法中,递归思想是非常重要的。使用递归能帮助我们简化代码。但要注意递归的结束条件。一个弄不好就会出现循环递归的情况,造成栈溢出(StackOverFlower)
什么是递归?
递归就是方法自己调用自己,每次调用时传入不同的变量。有助于我们解决复杂的编程问题。你可以把递归想象成俄罗斯套娃。一层套着一层。
话不多说,直接上两个小案例
打印输出
package com.algorithm.recursion;//打印问题public class printResult {public static void main(String[] args) {test(5);}private static void test(int n) {if(n>2) {test(n-1);}System.out.println(n);}}
求阶乘
package com.algorithm.recursion;//求阶乘问题public class Factorial {public static void main(String[] args) {int x=factorial(10);System.out.println("10的阶乘为"+x);}//求n的阶乘private static int factorial(int n) {if(n==1) {return 1;}return n*factorial(n-1);}}
通过以上两个小案例,相信你对递归已经开始有所了解了。下面我们了分析一下,递归调用时JVM的内部情况
JVM递归调用机制
每调用一次方法,就会在栈空间中开辟出一小块的内存空间。这部分空间的名字叫做栈帧。
每一个方法的调用对对应着栈帧空间。当出现无限递归的情况时,就会不停的压栈,最后导致栈溢出。
递归应用,迷宫问题
我们需要从蓝色的点走到黄色的点,应该怎么去走。这里用一个二维数组来模拟一下
package com.algorithm.recursion;//迷宫问题public class Maze {static int[][] map=new int[8][7];public static void main(String[] args) {//上下置为1for(int i=0;i<7;i++) {map[0][i]=1;map[7][i]=1;}//左右置为1for(int i=0;i<8;i++) {map[i][0]=1;map[i][6]=1;}//障碍物map[3][1]=1;map[3][2]=1;System.out.println("原始地图");print();findWay(map,1,1);System.out.println("移动后的地图");print();}public static boolean findWay(int[][] map,int i,int j) {if(map[6][5]==2) {return true;}else { //还在走向终点的过程中if(map[i][j]==0) { //如果这个点没有被走过map[i][j]=2;if(findWay(map,i+1,j)) { //向下走return true;}else if(findWay(map,i,j+1)) { //向右走return true;}else if(findWay(map,i-1,j)) { //向上走return true;}else if(findWay(map,i,j-1)) { //向左走return true;}else {//都走不通说明是死胡同map[i][j]=3;return false;}}else {return false;}}}private static void print() {for(int i=0;i<8;i++) {for(int j=0;j<7;j++) {System.out.print(map[i][j]+ " ");}System.out.println();}}}
八皇后问题
问题介绍
在8*8格的国际棋盘上摆放8个皇后,使其不能相互攻击,即:任意两个皇后都不能处于同一行、同一列或者同一斜线上。
算法思路:
- 第一个皇后先放在第一行第一列
- 第二个皇后放在第二行第一列,判断是否冲突。如果冲突,则向下移动一位。直到放到一个合适的位置为止
- 同样的道理,继续放第三、第四直到第八个皇后。当第八个皇后放好之后,表示找到了一个正确解。找到之后开始回溯。直到将第一个皇后放在第一列的解全部找到。
- 将第一个皇后放在第二列,继续往下找。
package com.algorithm;//八皇后问题public class Queen {int size=8; //皇后的数量//数组arr中索引表示第几个皇后,也表示皇后的行数。值表示列数int[] arr=new int[size]; static int count=0; //可以有多少种放法static int judgeCount=0; //程序进行了多少次冲突判断public static void main(String[] args) {Queen queen=new Queen();queen.put(0);System.out.println("一共有"+count+"中解法");System.out.println("一共要进行"+judgeCount+"次冲突判断");}//放置第n+1个皇后private void put(int n) {if(n==size) { //说明8个皇后已经放好了//打印皇后放置的位置printResult();return;}for(int i=0;i