原文鏈接:傳送門
迷宮問題
說明:
- 小球得到的路徑,和程序員設置的找路策略有關即:找路的上下左右的順序相關
- 再得到小球路徑時,可以先使用(下右上左),再改成(上右下左),看看路徑是不是有變化
- 測試回溯現象
- 思考: 如何求出最短路徑?
//下面代碼的找路策略是:下右上左
public static boolean setWay(int[][] map, int i, int j) {if (map[6][5] == 2) { // 表示路已經找到了return true;} else {if (map[i][j] == 0) { // 0: 可以走還沒有走// 這里開始遞歸回溯map[i][j] = 2; // 認為該點是可以走通,但是不一定if (setWay(map, i + 1, j)) { // 下找return true;} else if (setWay(map, i, j + 1)) { // 右return true;} else if (setWay(map, i - 1, j)) { // 上return true;} else if (setWay(map, i, j - 1)) { // 左return true;} else {// 走不通map[i][j] = 3;return false;}} else { //如果map(i)(j)!=0 //則值 1,2,3return false;}
}}
int[][] map = new int[8][7];
//上下全部置1
for(int i = 0 ; i<7;i++){map[0][i] = 1;map[7][i] = 1;
}
//左右全部置1
for (int i = 0; i< 8; i++) {map[i][0] = 1;map[i][6] = 1;
}
完整代碼
package com.atguigu.recursion;/*** ClassName: <br/>* Description: <br/>* Date: 2021-02-22 9:50 <br/>* @project data_algorithm* @package com.atguigu.recursion*/
public class MiGong {public static void main(String[] args) {// 先創建一個二維數組,模擬迷宮// 地圖int[][] map = new int[8][7];// 使用1 表示墻// 上下全部置為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;}//設置擋板, 1 表示map[3][1] = 1;map[3][2] = 1;
// map[1][2] = 1;
// map[2][2] = 1;// 輸出地圖System.out.println("地圖的情況");for (int i = 0; i < 8; i++) {for (int j = 0; j < 7; j++) {System.out.print(map[i][j] + " ");}System.out.println();}//使用遞歸回溯給小球找路//setWay(map, 1, 1);setWay2(map, 1, 1);//輸出新的地圖, 小球走過,并標識過的遞歸System.out.println("小球走過,并標識過的 地圖的情況");for (int i = 0; i < 8; i++) {for (int j = 0; j < 7; j++) {System.out.print(map[i][j] + " ");}System.out.println();}}//使用遞歸回溯來給小球找路//說明//1. map 表示地圖//2. i,j 表示從地圖的哪個位置開始出發 (1,1)//3. 如果小球能到 map[6][5] 位置,則說明通路找到.//4. 約定: 當map[i][j] 為 0 表示該點沒有走過 當為 1 表示墻 ; 2 表示通路可以走 ; 3 表示該點已經走過,但是走不通//5. 在走迷宮時,需要確定一個策略(方法) 下->右->上->左 , 如果該點走不通,再回溯/*** * @param map 表示地圖* @param i 從哪個位置開始找* @param j * @return 如果找到通路,就返回true, 否則返回false*/public static boolean setWay(int[][] map, int i, int j) {if(map[6][5] == 2) { // 通路已經找到okreturn true;} else {if(map[i][j] == 0) { //如果當前這個點還沒有走過//按照策略 下->右->上->左 走map[i][j] = 2; // 假定該點是可以走通.if(setWay(map, i+1, j)) {//向下走return true;} else if (setWay(map, i, j+1)) { //向右走return true;} else if (setWay(map, i-1, j)) { //向上return true;} else if (setWay(map, i, j-1)){ // 向左走return true;} else {//說明該點是走不通,是死路map[i][j] = 3;return false;}} else { // 如果map[i][j] != 0 , 可能是 1, 2, 3return false;}}}//修改找路的策略,改成 上->右->下->左public static boolean setWay2(int[][] map, int i, int j) {if(map[6][5] == 2) { // 通路已經找到okreturn true;} else {if(map[i][j] == 0) { //如果當前這個點還沒有走過//按照策略 上->右->下->左map[i][j] = 2; // 假定該點是可以走通.if(setWay2(map, i-1, j)) {//向上走return true;} else if (setWay2(map, i, j+1)) { //向右走return true;} else if (setWay2(map, i+1, j)) { //向下return true;} else if (setWay2(map, i, j-1)){ // 向左走return true;} else {//說明該點是走不通,是死路map[i][j] = 3;return false;}} else { // 如果map[i][j] != 0 , 可能是 1, 2, 3return false;}}}}
運行結果
地圖的情況
1 1 1 1 1 1 1
1 0 0 0 0 0 1
1 0 0 0 0 0 1
1 1 1 0 0 0 1
1 0 0 0 0 0 1
1 0 0 0 0 0 1
1 0 0 0 0 0 1
1 1 1 1 1 1 1
小球走過,并標識過的 地圖的情況
1 1 1 1 1 1 1
1 2 2 2 2 2 1
1 0 0 0 0 2 1
1 1 1 0 0 2 1
1 0 0 0 0 2 1
1 0 0 0 0 2 1
1 0 0 0 0 2 1
1 1 1 1 1 1 1 Process finished with exit code 0
通過遞歸,遍歷所有方式的路徑,共享棋盤中的數組位置數據
實現查找最優解
策略:下->右->上->左
最后噼里啪啦的回去了
回溯
原文鏈接:傳送門