广度优先搜索例2--走迷宫问题

走迷宫问题

迷宫是许多小方格构成的矩形,如下图所示,在每个小方格中有的是墙(图 中的“1”)有的是路(图中的“0”)。走迷宫就是从一个小方格沿着上,下,左,右四个方向都临近的方格,当然不能穿墙。设迷宫的入口是在左上角(1,1),出口是在右下角(8,8)。根据给定的迷宫,找出一条从入口到出口的路径。


/**
 *定义存放在队列里的数据类型
 *x,y表示访问的二维表的坐标,pre表示前驱节点编号。
 */
class Struct {
	int x, y, pre;

	Struct(int x, int y, int pre) {
		this.x = x;
		this.y = y;
		this.pre = pre;
	}
}

public class Main {
	/**
	 * 数组sq模拟一个队列
	 */
	static Struct sq[] = new Struct[100];
	
	public static void main(String[] args) {
		/**
		 * 数组maze存放迷宫二维表
		 */
		int maze[][] = { 
			{ 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 1, 1, 1, 1, 0, 1, 0 }, 
			{ 0, 0, 0, 0, 1, 0, 1, 0 },
			{ 0, 1, 0, 0, 0, 0, 1, 0 }, 
			{ 0, 1, 0, 1, 1, 0, 1, 0 },
			{ 0, 1, 0, 0, 0, 0, 1, 1 }, 
			{ 0, 1, 0, 0, 1, 0, 0, 0 },
			{ 0, 1, 1, 1, 1, 1, 1, 0 } 
			};
		/**
		 * 数组fx,fy组合使用表示可以搜索的上,下,左,右四个方向
		 */
		int fx[] = { 1, -1, 0, 0 };
		int fy[] = { 0, 0, -1, 1 };
		/**
		 * qh代表队列头
		 * qe代表队列尾
		 */
		int qh = 0;
		int qe = 1;
		int i,j;
		/**
		 * 访问过的地图位置标记为-1避免重复访问
		 * 由于题中说是从左上角开始访问,
		 * 所以左上角一定能访问,并先访问。
		 */
		maze[0][0] = -1;
		/**
		 * 第一个访问点入队列
		 */
		sq[1] = new Struct(1, 1, 0);
		while (qh != qe) {//当队头不等于对尾,表示队列不空
			qh++;         //出对列
			for (int k = 0; k < 4; k++) { //搜索四个方向
				i = sq[qh].x + fx[k];
				j = sq[qh].y + fy[k];
				if (check(i, j, maze)) {  //判断方向是否可达
					/**
					 * 入队列
					 */
					qe++;                
					sq[qe] = new Struct(i, j, qh);
					maze[i-1][j-1] = -1;
					/**
					 * 判断出口
					 */
					if (sq[qe].x == 8 && sq[qe].y == 8) {
						out1(qe);
						System.out.println();
						out2(qe);
						return;
					}
				}
			}
		}
	}

	/**
	 * 判断i,j位置是否可行
	 * @param i 横坐标(1~8)
	 * @param j 纵坐标(1~8)
	 * @param maze 地图
	 * @return
	 */
	static boolean check(int i, int j,int maze[][]) {
		if (i < 1 || i > 8 || j < 1 || j > 8) {
			return false;
		}
		if (maze[i-1][j-1] == 1 || maze[i-1][j-1] == -1) {
			return false;
		}
		return true;
	}
	
	/**
	 * 顺序输出
	 */
	static void out1(int qe){
		if(sq[qe].pre!=0){
			out1(sq[qe].pre);
			System.out.print("--("+sq[qe].x+","+sq[qe].y+")");
		}else{
			System.out.print("("+sq[qe].x+","+sq[qe].y+")");
		}
	}
	
	
	/**
	 * 逆序输出
	 */
	static void out2(int qe) {
		System.out.print("(" + sq[qe].x + "," + sq[qe].y+")");
		while (sq[qe].pre != 0) {
			qe = sq[qe].pre;
			System.out.print("--(" + sq[qe].x + "," + sq[qe].y + ")");
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值