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

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();

}

}

}

~~~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,816评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,729评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,300评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,780评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,890评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,084评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,151评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,912评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,355评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,666评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,809评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,504评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,150评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,121评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,628评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,724评论 2 351

推荐阅读更多精彩内容

  • 回溯算法 回溯法:也称为试探法,它并不考虑问题规模的大小,而是从问题的最明显的最小规模开始逐步求解出可能的答案,并...
    fredal阅读 13,636评论 0 89
  • Java经典问题算法大全 /*【程序1】 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子...
    赵宇_阿特奇阅读 1,852评论 0 2
  • 【程序1】 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔...
    叶总韩阅读 5,129评论 0 41
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,602评论 18 399
  • 想拥有曼妙的身姿吗?想拥有高贵的气质吗?想拥有健康的心态吗?美丽的女人们,动起来吧! 加入派澜舞蹈学院专业的舞蹈老...
    sznswudao阅读 443评论 0 0