BFS寬度優先搜索:應用最多的就是走迷宮問題
例如:給出一個5*5迷宮圖
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
如上圖的迷宮,入口,出口分別:左上角,右下角
"1"是牆壁,"0"是通路
求從左上角到右下角最短需要走多少步?
問題分析:
首先需要將每個點包裝成一個節點 x,y,deep
x:代表橫座標 y:代表縱座標 deep:代表該點的深度(相當於是步數)
1、在走的過程中肯定不能走之前走過的(題目求的爲最短),所以需要一個數組來標記該點是否被走過.
2、在走的過程中,需要判斷能不能移動
1、不能走出去 2、走的點必須是沒有走過的點 3、這個點是否能走
3、在滿足2的條件下,將該點加入到隊列(queue)當中
4、判斷是否已經走到了終點。如果已經到達了終點,結束程序
代碼:
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class 圖的bfs_迷宮 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int m = 5;
int n = 5;
int[][] graph = new int[m][n];
int[][] vis = new int[m][n];//標記哪些點已經被訪問
Queue<Node> queue = new LinkedList<>();
for(int i = 0;i<m;i++)
{
for(int j = 0;j<n;j++)
{
graph[i][j] = scanner.nextInt();
}
}
//初始化起點,深度爲0
Node start = new Node(0, 0, 0);
queue.add(start);
while (!queue.isEmpty()) {
Node poll = queue.poll();
int x = poll.x;
int y = poll.y;
int deep = poll.depth;
vis[x][y] = 1;//標註爲已訪問
//判斷是否到達終點
if (x == m - 1 && y == n - 1) {//走到出口
System.out.println(poll.depth);
break;
}
// 向左走,判斷1、不能走出去,2.左邊的位置沒有被訪問過,3.左邊位置上的值要和現在的值相同
//如果滿足條件的話,就添加到隊列當中
if (x - 1 >= 0 && vis[x - 1][y] == 0 && graph[x - 1][y] == 0) {
queue.add(new Node(x - 1, y, deep + 1));
}
// 向右走,判斷1、不能走出去,2.左邊的位置沒有被訪問過,3.左邊位置上的值要和現在的值相同
if (x + 1 < m && vis[x + 1][y] == 0 && graph[x + 1][y] == 0) {
queue.add(new Node(x + 1, y, deep + 1));
}
// 向下走,判斷1、不能走出去,2.左邊的位置沒有被訪問過,3.左邊位置上的值要和現在的值相同
if (y - 1 >= 0 && vis[x][y - 1] == 0 && graph[x][y - 1] == 0) {
queue.add(new Node(x, y - 1, deep + 1));
}
// 向上走,判斷1、不能走出去,2.左邊的位置沒有被訪問過,3.左邊位置上的值要和現在的值相同
if (y + 1 < n && vis[x][y + 1] == 0 && graph[x][y + 1] == 0) {
queue.add(new Node(x, y + 1, deep + 1));
}
}
}
static class Node {
int x;
int y;
int depth;//節點的深度相當於走的步數
public Node(int x, int y, int depth) {
this.x = x;
this.y = y;
this.depth = depth;
}
}
}
測試結果:
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
8