迷宫最短路径(BFS)

时间:2022-06-04 20:34:45

  用队列实现广度优先搜索(BFS),找出最短路径。用栈保存走过的路径,并输出路径和标识最短路径的地图。

输入用例: 0:路 1:墙壁

24 24
0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0
0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0
0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0
0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0
0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0
0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0
0 1 1 1 0 1 1 0 0 1 1 1 0 1 1 0 0 1 1 1 0 1 1 0
1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0
0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0
0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0
0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0
0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0
0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0
0 1 1 1 0 1 1 0 0 1 1 1 0 1 1 0 0 1 1 1 0 1 1 0
1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0
0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0
0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0
0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0
0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0
0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0
0 1 1 1 0 1 1 0 0 1 1 1 0 1 1 0 0 1 1 1 0 1 1 0
1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0

  这里需要在头文件中重新定义队列和栈的数据元素类型 SElemType, QElemType。

define.h

// define.h
#ifndef __MENGQL_DEFINE__
#define __MENGQL_DEFINE__

#define C_LOG_DBG(format, ...)
//printf("[%s@%s,%d] " format ,__FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__);
#define C_LOG_ERR(format, ...) printf("[%s@%s,%d] " format ,__FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__);
typedef
enum EStatus {ERROR, OK} Status;

typedef
struct
{
int x;
int y;
}PosType;

typedef
struct
{
PosType seat;
PosType parent;
}SElemType, QElemType;

#endif

Maze.c

  1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "define.h"
4 #include "SqQueue.h"
5 #include "SqStack.h"
6
7 int **g_MazeMap;
8 int g_m, g_n;//g_m:列数 g_n:行数
9
10 #define SHORTPRINT 5
11 #define FOOTPRINT 2
12
13 void MazePrint()
14 {
15 int i, j;
16 for(i=0; i<g_m; ++i)
17 {
18 for(j=0; j<g_n; ++j)
19 {
20 printf("%d ", g_MazeMap[i][j]);
21 }
22 printf("\n");
23 }
24 }
25 void MarkShortPrint(PosType pos)
26 {
27 g_MazeMap[pos.y][pos.x] = SHORTPRINT;
28 }
29 void MazePrintRes(SqStack *S, int x, int y)
30 {
31 SElemType e;
32 while(StackEmpty(S) != OK)
33 {
34 PopStack(S, &e);
35 if(e.seat.x == x && e.seat.y == y)
36 {
37 MazePrintRes(S, e.parent.x, e.parent.y);
38 MarkShortPrint(e.seat);
39 printf("[%d][%d]\n", x, y);
40 }
41 }
42 return;
43 }
44 Status MazePass(PosType pos)
45 {
46 if(pos.x>=0 && pos.y>=0 && pos.x<g_m && pos.y<g_n && g_MazeMap[pos.y][pos.x] == 0)
47 {
48 return OK;
49 }
50 return ERROR;
51 }
52 void MazeFootPrint(PosType pos)
53 {
54 g_MazeMap[pos.y][pos.x] = FOOTPRINT;
55 }
56 void NextPos(PosType *pos, int di)
57 {
58 switch(di)
59 {
60 case 1:
61 pos->y = pos->y-1;
62 break;
63 case 2:
64 pos->x = pos->x-1;
65 break;
66 case 3:
68 pos->y = pos->y+1;
69 break;
70 case 4:
71 pos->x = pos->x+1;
72 break;
73 defult:
74 break;
75 }
76 }
77 Status MazeShortPath(PosType *start, PosType *end)
78 {
79 PosType curPos, nextPos;
80 SElemType e;
81 SqQueue Q;
82 SqStack resS;//保存遍历过的节点,用于输出结果
83 int i;
84
85 e.parent.x = -1;
86 e.parent.y = -1;
87 e.seat.x = start->x;
88 e.seat.y = start->y;
89
90 if(InitQueue(&Q) != OK || InitStack(&resS) != OK)
91 {
92 return ERROR;
93 }
94 do
95 {
96 PushStack(&resS, e);
97 curPos.x = e.seat.x;
98 curPos.y = e.seat.y;
99 for(i=1; i<5; ++i)
100 {
101 C_LOG_DBG("[%d][%d][%d]\n", curPos.x, curPos.y, i);
102 nextPos.x = curPos.x;
103 nextPos.y = curPos.y;
104 NextPos(&nextPos, i);
105 if(MazePass(nextPos) == OK)
106 {
107 C_LOG_DBG("[%d][%d][%d][%d][%d]\n", curPos.x, curPos.y, nextPos.x, nextPos.y);
108 e.parent.x = curPos.x;
109 e.parent.y = curPos.y;
110 e.seat.x = nextPos.x;
111 e.seat.y = nextPos.y;
112
113 EnQueue(&Q, e);
114 MazeFootPrint(nextPos);
115
116 if(nextPos.x == end->x && nextPos.y == end->y)
117 {
118 C_LOG_DBG("%s\n", "DEBUG");
119 PushStack(&resS, e);
120 MazePrintRes(&resS, nextPos.x, nextPos.y);
121 MazePrint();
122 return OK;
123 }
124 }
125 }
126 }while(DeQueue(&Q, &e) == OK);
127 MazePrint();
128 DestoryStack(&resS);
129 DestroyQueue(&Q);
130 return ERROR;
131 }
132
133 int main()
134 {
135 int i, j;
136 PosType start;
137 PosType end;
138
139 scanf("%d %d", &g_m, &g_n);
140 start.x = 0;
141 start.y = 0;
142 end.x = g_m-1;
143 end.y = g_n-1;
144
145 g_MazeMap=(int**)malloc(g_m*sizeof(int*));
146 for(i=0; i<g_m; ++i)
147 {
148 g_MazeMap[i] = (int*)malloc(g_n*sizeof(int));
149 }
150 for(i=0; i<g_m; ++i)
151 {
152 for(j=0; j<g_n; ++j)
153 {
154 scanf("%d", &g_MazeMap[i][j]);
155 }
156 }
157 MazeShortPath(&start, &end);
158 }

输出结果(路径坐标):

[0][0]
[
0][1]
[
0][2]
[
0][3]
[
0][4]
[
1][4]
[
2][4]
[
2][5]
[
3][5]
[
4][5]
[
4][6]
[
4][7]
[
5][7]
[
6][7]
[
7][7]
[
7][8]
[
7][9]
[
7][10]
[
7][11]
[
7][12]
[
8][12]
[
9][12]
[
10][12]
[
10][13]
[
11][13]
[
12][13]
[
12][14]
[
12][15]
[
13][15]
[
14][15]
[
15][15]
[
15][16]
[
15][17]
[
15][18]
[
15][19]
[
15][20]
[
16][20]
[
17][20]
[
18][20]
[
18][21]
[
19][21]
[
20][21]
[
20][22]
[
20][23]
[
21][23]
[
22][23]
[
23][23]

输出结果(路径地图):0:没走过的路 1:墙壁 2:走过的路 5:走过的路中的最短路径

5 2 1 2 2 2 1 2 2 2 1 2 2 2 1 2 2 2 1 2 2 2 1 2 
5 2 1 2 2 2 1 2 2 2 1 2 2 2 1 2 2 2 1 2 2 2 1 2
5 2 2 2 1 1 2 2 2 2 2 2 1 1 2 2 2 2 2 2 1 1 2 2
5 1 1 1 1 2 2 2 2 1 1 1 1 2 2 2 2 1 1 1 1 2 2 2
5 5 5 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2
2 1 5 5 5 1 2 2 2 1 2 2 2 1 2 2 2 1 2 2 2 1 2 2
2 1 1 1 5 1 1 2 2 1 1 1 2 1 1 2 2 1 1 1 2 1 1 2
1 2 2 2 5 5 5 5 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2
2 2 1 2 2 2 1 5 2 2 1 2 2 2 1 2 2 2 1 2 2 2 1 2
2 2 1 2 2 2 1 5 2 2 1 2 2 2 1 2 2 2 1 2 2 2 1 2
2 2 2 2 1 1 2 5 2 2 2 2 1 1 2 2 2 2 2 2 1 1 2 2
2 1 1 1 1 2 2 5 2 1 1 1 1 2 2 2 2 1 1 1 1 2 2 2
2 2 2 1 2 2 2 5 5 5 5 1 2 2 2 2 2 2 2 1 2 2 2 2
2 1 2 2 2 1 2 2 2 1 5 5 5 1 2 2 2 1 2 2 2 1 2 2
2 1 1 1 2 1 1 2 2 1 1 1 5 1 1 2 2 1 1 1 2 1 1 2
1 2 2 2 2 2 2 2 1 2 2 2 5 5 5 5 1 2 2 2 2 2 2 2
2 2 1 2 2 2 1 2 2 2 1 2 2 2 1 5 2 2 1 2 2 2 1 2
2 2 1 2 2 2 1 2 2 2 1 2 2 2 1 5 2 2 1 2 2 2 1 2
2 2 2 2 1 1 2 2 2 2 2 2 1 1 2 5 2 2 2 2 1 1 2 2
2 1 1 1 1 2 2 2 2 1 1 1 1 2 2 5 2 1 1 1 1 2 2 2
2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 5 5 5 5 1 2 2 2 2
2 1 2 2 2 1 2 2 2 1 2 2 2 1 2 2 2 1 5 5 5 1 2 2
2 1 1 1 2 1 1 2 2 1 1 1 2 1 1 2 2 1 1 1 5 1 1 0
1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 5 5 5 5