此次迷宫深度优先遍历寻找路径采用栈结构,每个节点都有固定的行走方向(右下左上),除非一个方向走不通,不然会一条道走到黑。
如果路径存在,打印出行走路径,否则打印出迷宫不存在有效路径。
方向常量定义:
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 *
缺点:深度优先无法求出迷宫最短路径,下一篇广度优先遍历可以求出最短路径。