此次迷宮深度優先遍歷尋找路徑采用棧結構,每個節點都有固定的行走方向(右下左上),除非一個方向走不通,不然會一條道走到黑。
如果路徑存在,打印出行走路徑,否則打印出迷宮不存在有效路徑。
方向常量定義:
public interface Constant { // 右方向
int RIGHT = 0; // 下方向
int DOWN = 1; // 左方向
int LEFT = 2; // 上方向
int UP = 3; }
所用到的棧定義(jdk自帶的棧或集合也可以實現此功能)
/** * 描述:實現迷宮路徑搜索需要的鏈式棧結構 * * @Author shilei * @Date 2019/5/18 */
public class Stack<T> { // top指向頭節點,頭節點的后面就是棧頂節點
private Entry<T> top; public Stack() { this.top =new Entry<>(null,null); } /** * 入棧操作 * @param val */
public void push(T val){ Entry<T> newEntry=new Entry<>(val,this.top.next); this.top.next=newEntry; } /** * 出棧操作 * @return
*/
public T pop(){ Entry<T> entry=this.top.next; this.top.next=this.top.next.next; return entry.data; } /** * 查看棧頂元素 * @return
*/
public T peek(){ if(isEmpty())return null; return this.top.next.data; } /** * 判斷棧空 * @return
*/
public boolean isEmpty(){ return this.top.next==null; } /** * 節點類型定義 * @param <T> */
static class Entry<T>{ T data; Entry<T> next; public Entry(T data, Entry<T> next) { this.data = data; this.next = next; } } }
迷宮節點類型定義
/** * 描述: 定義迷宮節點類型 */
private static class MazeNode { // 節點的值
int val; // 節點的x和y坐標
int x; int y; // 節點四個方向的行走狀態,true表示可以走,false表示不能走
boolean[] state; /** * 迷宮路徑初始化 * @param data * @param i * @param j */
public MazeNode(int data, int i, int j){ this.state = new boolean[4]; this.val = data; this.x = i; this.y = j; } }
迷宮類型定義
/** * 描述: 迷宮的類型定義 * * @Author shilei * @Date 2019/5/18 */
public class Maze { // 迷宮所有的路徑存儲在二維數組當中
private MazeNode[][] maze; // 存儲迷宮路徑節點的棧 深度優先
private Stack<MazeNode> stack;// 迷宮的行數
private int row; // 迷宮的列數
private int col; /** * 迷宮初始化 * @param row * @param col */
public Maze(int row, int col) { this.row = row; this.col = col; this.maze = new MazeNode[row][col]; this.stack = new Stack<>(); } /** * 初始化指定位置的迷宮節點 * @param data * @param i * @param j */
public void initMazeNode(int data, int i, int j) { this.maze[i][j] = new MazeNode(data, i, j); } /** * 修改迷宮所有節點四個方向的行走狀態信息 */
public void initMazeNodePathState() { for (int i=0;i<row;i++){ for (int j=0;j<col;j++){ if(j+1<col&&maze[i][j+1].val==0){ maze[i][j].state[Constant.RIGHT]=true; } if(i+1<row&&maze[i+1][j].val==0){ maze[i][j].state[Constant.DOWN]=true; } if(j>0&&maze[i][j-1].val==0){ maze[i][j].state[Constant.LEFT]=true; } if(i>0&&maze[i-1][j].val==0){ maze[i][j].state[Constant.UP]=true; } } } } /** * 尋找迷宮路徑 */
public void findMazePath() { // 深度優先
if (maze[0][0].val != 0) { return; } stack.push(maze[0][0]); while (!stack.isEmpty()) { MazeNode top = stack.peek(); //找到出口
if (top.x == row - 1 && top.y == col - 1) { break; } if (top.state[Constant.RIGHT]) { top.state[Constant.RIGHT] = false; stack.push(maze[top.x][top.y + 1]); this.stack.peek().state[Constant.LEFT] = false; continue; } if (top.state[Constant.DOWN]) { top.state[Constant.DOWN] = false; stack.push(maze[top.x + 1][top.y]); this.stack.peek().state[Constant.UP] = false; continue; } if (top.state[Constant.LEFT]) { top.state[Constant.LEFT] = false; stack.push(maze[top.x][top.y - 1]); this.stack.peek().state[Constant.RIGHT] = false; continue; } if (top.state[Constant.UP]) { top.state[Constant.UP] = false; stack.push(maze[top.x - 1][top.y]); this.stack.peek().state[Constant.DOWN] = false; continue; } stack.pop(); }
} /** * 打印迷宮路徑搜索的結果 */
public void showMazePath(){ if(this.stack.isEmpty()){ System.out.println("迷宮出不去咯"); }else { while (!stack.isEmpty()){ MazeNode top=stack.pop(); maze[top.x][top.y].val='*'; } for (int i = 0; i <row ; i++) { for (int j = 0; j <col ; j++) { if(maze[i][j].val=='*'){ System.out.print("*"+" "); continue; } System.out.print(maze[i][j].val+" "); } System.out.println(); } }
} /** * 描述: 定義迷宮節點類型 */
private static class MazeNode { // 節點的值
int val; // 節點的x和y坐標
int x; int y; // 節點四個方向的行走狀態,true表示可以走,false表示不能走
boolean[] state; /** * 迷宮路徑初始化 * @param data * @param i * @param j */
public MazeNode(int data, int i, int j){ this.state = new boolean[4]; this.val = data; this.x = i; this.y = j; } } }
測試類
public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); System.out.print("請輸入迷宮的行列數:"); int row, col, data; row = in.nextInt(); col = in.nextInt(); Maze maze = new Maze(row, col); System.out.println("請輸入迷宮路徑"); for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { data = in.nextInt(); maze.initMazeNode(data, i, j); } } // 修改迷宮所有節點四個方向的行走狀態信息
maze.initMazeNodePathState(); // 尋找迷宮路徑
maze.findMazePath(); // 打印迷宮路徑搜索的結果
maze.showMazePath(); } }
結果:
請輸入迷宮的行列數:4 5 請輸入迷宮路徑 0 1 0 0 0
0 0 0 1 0
1 0 1 1 0
0 0 0 0 0
* 1 * * *
* * * 1 *
1 0 1 1 *
0 0 0 0 *
缺點:深度優先無法求出迷宮最短路徑,下一篇廣度優先遍歷可以求出最短路徑。
