美文网首页直通BAT算法与数据结构
java实现用链式栈求解迷宫问题--(2)实现迷宫的搜索算法

java实现用链式栈求解迷宫问题--(2)实现迷宫的搜索算法

作者: 顾子豪 | 来源:发表于2017-10-29 10:37 被阅读33次
    maze.txt(*代表可通,#代表不通)

    /**

    * 1 从maze.txt读入迷宫

    * 2 从入口坐标(1,1)寻找到出口的通路

    * 3 显示迷宫中数据

    * 0 退出程序

    * MazeApp

    * 创建人:guxiaohao

    * 时间:2017年10月29日-上午9:56:52

    * @version 1.0.0

    *

    */

    public class MazeApp {

    // 程序菜单

    static void menu() {

    System.out.println("\t***********迷宫问题*****************");

    System.out.println("\t*  1 从maze.txt读入迷宫                                  *");

    System.out.println("\t*  2 从入口坐标(1,1)寻找到出口的通路  *");

    System.out.println("\t*  3 显示迷宫中数据                                            *");

    System.out.println("\t*  0 退出程序                                                            *");

    System.out.println("\t***********************************");

    System.out.println("\t请输入菜单项:");

    }

    //程序入口

    public static void main(String[] args) {

    Maze maze = null;

    int choice;

    boolean flag = false;

    MazeApp md = new MazeApp();

    Scanner sc = null;

    sc = new Scanner(System.in);

    while (true) {

    menu();// 显示菜单

    choice = sc.nextInt();// 输入菜单选项

    switch (choice) {

    case 1:

    // 读取迷宫信息

    maze = md.loadMaze();

    flag = true; // 可以求迷宫路径了

    break;

    case 2:

    if (maze != null && flag) {

    // 求迷宫入口到出口的路径

    if (!md.searchMazePath(maze))

    System.out.println("迷宫中从(1,1)到(" + (maze.rowNum - 2)

    + "," + (maze.colNum - 2) + ")不存在通路!");

    flag = false; // 不能重复求迷宫路径,除非再次加载迷宫数据。

    } else {

    System.out.println("先执行菜单1,加载或再次加载迷宫数据!");

    }

    break;

    case 3:

    if (maze != null) {

    // 显示迷宫的内容(包括围栏),*代表可通,#代表不通

    printMaze(maze);

    } else {

    System.out.println("尚未加载迷宫数据!");

    }

    break;

    case 0:

    sc.close();

    System.exit(0);

    break;

    default:

    System.out.println("菜单选择错误,请重新输入!\n");

    }

    }

    }

    // 定义描述迷宫中当前位置的类

    class T {

    int x; // x代表当前位置的行坐标

    int y; // y代表当前位置的列坐标

    int dir; // 0——东;1——南;2——西;3——北;4——不通

    T() {

    this.x = 1;

    this.y = 1;

    this.dir = 0;

    }

    T(int x, int y, int dir) {

    this.x = x;

    this.y = y;

    this.dir = dir;

    }

    }

    class Maze {

    char mat[][] = null; // 定义二维数组存取迷宫

    int rowNum = 0, colNum = 0;

    }

    // 从文件中加载(读取)迷宫数据

    private Maze loadMaze() {

    Maze maze = new Maze();

    BufferedReader br = null;

    try {

    br = new BufferedReader(new FileReader(new File("maze.txt")));

    String rc[] = br.readLine().trim().split(" "); // 先读入迷宫的行数和列数

    maze.rowNum = Integer.parseInt(rc[0]);

    maze.colNum = Integer.parseInt(rc[1]);

    maze.mat = new char[maze.rowNum][]; // 存储迷宫数据的二维数组

    for (int i = 0; i < maze.rowNum; i++) {

    // 每次读入迷宫数据的一行,并转换成char类型的数组

    maze.mat[i] = br.readLine().trim().toCharArray();

    if (maze.mat[i].length != maze.colNum) {

    System.out.println("数据文件中的迷宫行列数有误,请检查数据文件!");

    return null;

    }

    }

    } catch (FileNotFoundException e) {

    e.printStackTrace();

    } catch (IOException e) {

    e.printStackTrace();

    } finally {

    try {

    br.close();

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

    printMaze(maze);// 显示迷宫

    System.out.println("迷宫数据加载成功!");

    return maze; // 返回迷宫对象

    }

    /**

    * 搜索从左上角到右下角的迷宫通道

    * 定义一个标志数组mark[][],用来标记走过的路径,并全部赋初值为0(表示未走过),每走过一个坐标,就记当前标记为1

    * app

    * 方法名:searchMazePath

    * 创建人:guxiaohao

    * 时间:2017年10月29日-上午9:42:32

    * @param maze

    * @return boolean

    * @exception

    * @since  1.0.0

    */

    private boolean searchMazePath(Maze maze) {

    LinkedStack ls = new LinkedStack();

    int mark[][] = new int[maze.rowNum-1][maze.colNum-1];

    for ( int i=1;i<maze.rowNum-1;i++)

    for ( int j=1;j<maze.colNum-1;j++)

    mark[i][j]=0;

    T t = new T();

    int tX = 1;

    int tY = 1;

    ls.push(t);

    while( !ls.isEmpty() ){

    T mt = (T) ls.getTop();//每次循环把栈顶元素给mt

    tX = mt.x;

    tY = mt.y;

    if ( tX==maze.rowNum-2 && tY==maze.colNum-2 ) {

    mt.dir = 0;

    break;

    }

    if ( maze.mat[tX][tY+1] == '*' && mark[tX][tY+1] == 0 ) { //东方

    mt.dir = 0;

    ls.push(new T(tX,tY+1,0));

    mark[tX][tY+1] = 1;

    } else if ( maze.mat[tX+1][tY] == '*' && mark[tX+1][tY] == 0 ) { //南方

    mt.dir = 1;

    ls.push(new T(tX+1,tY,1));

    mark[tX+1][tY] = 1;

    } else if ( maze.mat[tX][tY-1] == '*' && mark[tX][tY-1] == 0 ) { //西方

    mt.dir = 2;

    ls.push(new T(tX,tY-1,2));

    mark[tX][tY-1] = 1;

    } else if ( maze.mat[tX-1][tY] == '*' && mark[tX-1][tY] == 0 ) { //北方

    mt.dir = 3;

    ls.push(new T(tX-1,tY,3));

    mark[tX-1][tY] = 1;

    } else {

    ls.pop();

    maze.mat[tX][tY] = 'Y';

    }

    }

    if ( ls.isEmpty() ){

    return false;

    } else {

    printPath(maze, ls);

    return true;

    }

    }

    // 显示迷宫中的通路

    private void printPath(Maze maze, LinkedStack s) {

    // 定义一个栈,按从出口到入口依次进栈,出栈输出即可得到路径

    LinkedStack t = new LinkedStack();

    for (int i = 0; i < maze.rowNum; i++) {

    maze.mat[i] = Arrays.copyOf(maze.mat[i], maze.mat[i].length);

    }

    // 由于s的栈顶时目标,所以先把s中的结点全部导入到t

    while (!s.isEmpty())

    t.push(s.pop());

    System.out.println("迷宫中的通道路径为:");

    // 输出路径,包括行坐标,列坐标,下一个位置方向

    while (!t.isEmpty()) { // 栈非空,继续输出

    T tmp = (T) t.pop();

    System.out.print("(" + tmp.x + "," + tmp.y + ",");// 输出行坐标,列坐标

    switch (tmp.dir) // 输出相应的方向

    {

    case 0:

    System.out.println("→)");

    maze.mat[tmp.x][tmp.y] = '→';

    break;

    case 1:

    System.out.println("↓)");

    maze.mat[tmp.x][tmp.y] = '↓';

    break;

    case 2:

    System.out.println("←)");

    maze.mat[tmp.x][tmp.y] = '←';

    break;

    case 3:

    System.out.println("↑)");

    maze.mat[tmp.x][tmp.y] = '↑';

    break;

    }

    }

    }

    // 显示加载的迷宫内容(包括四周的围栏),*代表可通,#代表不通

    private static void printMaze(Maze maze) {

    for (int i = 0; i < maze.rowNum; i++) {

    for (int j = 0; j < maze.colNum; j++)

    System.out.print(maze.mat[i][j]);

    System.out.println();

    }

    }

    }

    相关文章

      网友评论

        本文标题:java实现用链式栈求解迷宫问题--(2)实现迷宫的搜索算法

        本文链接:https://www.haomeiwen.com/subject/pxtypxtx.html