對於圖這種數據結構,最基礎的就是它的遍歷方式。
在書上看到一段話:對於無權的圖,使用廣搜就可以獲得其路徑,對於有權圖就不可以。
無權的圖,就相當於每條邊的權為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 }
結果,上圖:
廣搜很好實現。在設計點坐標時,需要幾個參量:
x,y;
上一個節點x,y;
已經走的步數。
配合這個左邊點數據結構不斷進入隊列,當此節點碰到邊界時則走出去,函數返回則是最短路徑。
不return,則會輸出所有的路徑和步數。