迷宮——BFS(最短路徑和所有路徑)


對於圖這種數據結構,最基礎的就是它的遍歷方式。

在書上看到一段話:對於無權的圖,使用廣搜就可以獲得其路徑,對於有權圖就不可以。

無權的圖,就相當於每條邊的權為1。迷宮就是最簡單的一種無權圖,每一步都是一個節點,節點和節點之間的邊長都為1。

為了驗證這個思想,自己定義一個迷宮,通過BFS獲得可以走出去的所有路徑和最短的路徑。

BFS就是以一個起點,配合隊列,向四面八方進行搜索,搜過過了就更改標記表示已經走過了。

 1 #include <iostream>
 2 #include <fstream>
 3 #include <vector>
 4 #include <algorithm>
 5 #include <string>
 6 #include <list>
 7 #include <stack>
 8 #include <queue>
 9 
10 using namespace std;
11 
12 typedef struct point{
13     int x;
14     int y;
15     point *previous;
16     int step;
17 } point;
18 
19 point dir[4] = {
20     { 0, 1, NULL, 0 },
21     { 1, 0, NULL, 0 },
22     { 0, -1, NULL, 0 },
23     { -1, 0, NULL, 0 },
24 };
25 
26 //只有0位置可以走,到數組邊緣就是走出迷宮。
27 //輸出最短的路徑和最短步數
28 int map[8][8] = {
29     { 1, 0, 1, 1, 1, 1, 1, 1 },
30     { 1, 0, 0, 0, 0, 0, 0, 1 },
31     { 1, 0, 1, 1, 1, 1, 0, 1 },
32     { 1, 0, 0, 0, 0, 1, 0, 0 },
33     { 1, 1, 1, 1, 0, 0, 1, 1 },
34     { 1, 1, 1, 1, 1, 0, 1, 1 },
35     { 1, 1, 0, 0, 0, 0, 1, 1 },
36     { 1, 1, 0, 1, 1, 1, 1, 1 },
37 };
38 
39 void PrintAllPath(point *p)
40 {
41     int shortest = p->step;
42     
43     cout << "可行短路徑為:";
44     while (p->previous != NULL)
45     {
46         cout << "(" << p->x << "," << p->y << ")";
47         p = p->previous;
48     }
49     cout << "(" << p->x << "," << p->y << ")" << endl;
50     cout << "路徑長度為:" << shortest << endl;
51 }
52 
53 void BFS(point startPoint)
54 {
55     queue<point> q;
56     q.push(startPoint);
57     point cur;
58 
59     while (!q.empty())
60     {
61         cur = q.front();
62         q.pop();
63         map[cur.x][cur.y] = 1;
64 
65         for (int i = 0; i < 4; i++)
66         {
67             point nxt{ cur.x + dir[i].x, cur.y + dir[i].y, NULL, 0 };
68             if (nxt.x >= 0 && nxt.x < 8 && nxt.y >= 0 && nxt.y < 8 && map[nxt.x][nxt.y] == 0)
69             {
70                 point *tmp = new point;
71                 memcpy(tmp, &cur, sizeof(point));
72                 nxt.previous = tmp;
73                 nxt.step = cur.step + 1;
74                 map[nxt.x][nxt.y] = 1;
75 
76                 if (nxt.x == 0 || nxt.x == 7 || nxt.y == 0 || nxt.y == 7)
77                 {
78                     PrintAllPath(&nxt);
79 
80                     //這句話注釋則輸出所有路徑,不注釋是最短路徑
81                     //return;
82                 }
83                 q.push(nxt);
84             }
85         }
86     }
87 }
88 
89 int main()
90 {
91     point startPoint{ 0, 1, NULL, 0 };
92     BFS(startPoint);
93 
94     return 0;
95 }
View Code

結果,上圖:

廣搜很好實現。在設計點坐標時,需要幾個參量:

x,y;

上一個節點x,y;

已經走的步數。

配合這個左邊點數據結構不斷進入隊列,當此節點碰到邊界時則走出去,函數返回則是最短路徑。

不return,則會輸出所有的路徑和步數。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM