定義
遞歸就是自己調用自己。
遞歸必須具備的條件
- 子問題與原問題解決的是相同的事
- 不能無限制的調用自身,必須有有效的邊界條件可以跳出。
遞歸調用的底層規則
- 當程序執行一個方法時,就會在底層開闢一個獨立的棧
- 每個空間的局部變量是獨立的,如果是引用變量,則所有空間共用這個引用變量
- 遞歸時,當一個方法執行完或者執行
return
語句時,遵守誰調用返回給誰的原則
遞歸的迷宮實現
利用二維數組實現一個迷宮地圖。在地圖上,數字1表示迷宮的牆壁,數字0表示還未走的地方。
在程序執行時,數字2表示已經走過的地方,數字3表示此路走過且此路不通。
/**
* 迷宮問題
*
* 1 迷宮牆壁, 2 可走且走過的路, 3 走過且不可走的路, 0 未走的路
*/
public class MazeDemo {
public static void main(String[] args) {
int[][] maze = creatMaze();
//printMaze(maze);
setWay(maze, 1, 1);
printMaze(maze);
}
/**
* 迷宮的創建
*/
public static int[][] creatMaze() {
int[][] maze = new int[8][7];
for(int i = 0; i < 7; i++) {
maze[0][i] = 1;
maze[7][i] = 1;
}
for(int i = 0; i < 8; i++) {
maze[i][0] = 1;
maze[i][6] = 1;
}
maze[3][1] = 1;
maze[3][2] = 1;
return maze;
}
/**
* 迷宮的打印
*/
public static void printMaze(int[][] maze) {
for(int i = 0; i < maze.length; i++) {
for(int j = 0; j< maze[i].length; j++) {
System.out.printf("%d\t", maze[i][j]);
}
System.out.println();
}
}
/**
* 迷宮查找路徑
* 從(1,1)到(6,5)
* 上——》右——》下——》左
*/
public static boolean setWay(int[][] maze, int row, int col) {
if(maze[6][5] == 2) {
return true;
} else {
if(maze[row][col] == 0) {
maze[row][col] = 2;
if(setWay(maze, row - 1, col)) {
return true;
} else if(setWay(maze, row, col + 1)) {
return true;
} else if(setWay(maze, row + 1, col)) {
return true;
} else if(setWay(maze, row, col - 1)) {
return true;
} else {
maze[row][col] = 3;
return false;
}
} else {
return false;
}
}
}
}
遞歸實現八皇后問題
在8×8格的國際象棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,問有多少種擺法。
/**
* 8皇后問題
*/
public class Queen {
final static int max = 8;
private static int[] arr = new int[max];
private static int count = 0;
public static void main(String[] args) {
check(0);
System.out.println("共有" + count + "中方法");
}
/**
* 打印一種情況
*/
public static void printOne() {
count++;
for(int i = 0; i < arr.length; i++) {
System.out.printf("%d\t", arr[i]);
}
System.out.println();
}
/**
* 判斷是否符合第n個皇后是否的條件
*/
public static boolean Judge(int n) {
for(int i = 0; i < n; i++) {
//arr[i] == arr[n] 判斷是否處於 同一列
//Math.abs(n - i) == Math.abs(arr[n] - arr[i]) 判斷是否處於同一斜線
if(arr[i] == arr[n] || Math.abs(n - i) == Math.abs(arr[n] - arr[i])) {
return false;
}
}
return true;
}
/**
* 獲取所有的問題解法
*/
public static void check(int n) {
if(n == max) {
printOne();
return;
} else {
for(int i = 0; i < max; i++) {
arr[n] = i;
if(Judge(n)) {
check(n + 1);
}
}
}
}
}