數據結構和算法學習日記——遞歸

定義

遞歸就是自己調用自己。

遞歸必須具備的條件

  • 子問題與原問題解決的是相同的事
  • 不能無限制的調用自身,必須有有效的邊界條件可以跳出。

遞歸調用的底層規則

  • 當程序執行一個方法時,就會在底層開闢一個獨立的棧
  • 每個空間的局部變量是獨立的,如果是引用變量,則所有空間共用這個引用變量
  • 遞歸時,當一個方法執行完或者執行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);
				}
			}
		}		
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章