对于图这种数据结构,最基础的就是它的遍历方式。
在书上看到一段话:对于无权的图,使用广搜就可以获得其路径,对于有权图就不可以。
无权的图,就相当于每条边的权为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,则会输出所有的路径和步数。