广度搜索--迷宫解救

package com.xjj.Ah;

import java.util.LinkedList;
import java.util.Scanner;

/*-----广度优先搜索BFS-----队列入队形式--
 * 1. 一层一层的扩展:扩展时每发现一个可行点就将此点放入队列中,然后移除头结点,从新的头结点又开始层次搜索...
 * 2. 此题为迷宫解救:每个点只入队一次
 * 
 * */
public class Ah_4_3 {
	static int[][]	a = new int[51][51];					//存迷宫
	static int[][] book = new int[51][51];					//标记是否走过
	static int[][] dir = {{0,1},{1,0},{0,-1},{-1,0}};		//方向数组,右下左上(顺时针),精妙之处(方便递归枚举)
	static int p,q,n,m,min = Integer.MAX_VALUE;
	
	//新座标对象
	static class Dis{
		int x;
		int y;
		int dis;
	}
	
	public void bfs(int startx, int starty){
		
		LinkedList<Dis> list = new LinkedList<>();	//创建队列
		Dis d = new Dis();							//新座标对象
		d.x = startx;
		d.y = starty;
		d.dis = 0;
		list.add(d);								//入队
		book[startx][starty] = 1;					//标记该点已经入队,不重复
		int flag = 0;								//标记未找到目标
		
		while(!list.isEmpty()){
			//枚举四个方向
			for(int k = 0; k <= 3; k++){
				//先向右移动
				int tx = list.getFirst().x + dir[k][0];
				int ty = list.getFirst().y + dir[k][1];
				//是否越界
				if (tx<1 || ty<1 || tx>n || ty>m) {
					continue;
				}
				//判断不为障碍物并且没有入队中
				if (a[tx][ty] == 0 && book[tx][ty] == 0){
					book[tx][ty] = 1;
					d = new Dis();
					d.x = tx;
					d.y = ty;
					//一定为头结点dis + 1
					d.dis = list.getFirst().dis + 1;
					list.add(d);
				}
				//如果等于目标节点
				if (tx == p && ty == q) {
					flag = 1;
					break;
				}
			}
			if (flag == 1) 
				break;
			list.removeFirst();
		}
		System.out.println("最短路径为: " + d.dis);
		
	}

	public static void main(String[] args) {
		System.out.println("输入迷宫(n为行,m为列):");
		Scanner scanner = new Scanner(System.in);
		n = scanner.nextInt();
		m = scanner.nextInt();
		
		for(int i = 1; i <= n; i++)
			for(int j = 1; j <= m; j++){
				a[i][j] =scanner.nextInt();
			}
		p = 1;
		q = 4;
		Ah_4_3 ah = new Ah_4_3();
		ah.bfs(1, 1);

	}

}

点赞