用C语言问题描述:以一个m*n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论
时间: 2023-09-17 10:06:40 浏览: 113
以下是C语言实现迷宫问题的算法:
1. 定义一个 m * n 的迷宫数组 maze,其中 0 表示通路,1 表示障碍物。
2. 定义一个同样大小的 visited 数组,用于记录某个点是否已经被访问过。
3. 定义一个结构体 node,存储每个节点的坐标和到起点的步数。
4. 定义一个队列 queue,用于存储待访问的节点。
5. 将起点加入队列,并将其标记为已访问。
6. 循环执行以下步骤直到队列为空:
1. 取出队列的首节点,记为 cur。
2. 如果 cur 为终点,则返回路径。
3. 否则,遍历 cur 的上下左右四个方向的邻居节点,记为 next:
- 如果 next 没有越界且为通路且未被访问过,则将其加入队列,并标记为已访问。
7. 如果队列为空仍未找到终点,则说明无解。
以下是代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_SIZE 100
// 定义迷宫和访问数组
int maze[MAX_SIZE][MAX_SIZE];
bool visited[MAX_SIZE][MAX_SIZE];
// 定义节点结构体
typedef struct {
int x, y; // 坐标
int step; // 到起点的步数
} node;
// 定义队列结构体
typedef struct {
node data[MAX_SIZE * MAX_SIZE];
int front, rear;
} queue;
// 初始化队列
void init_queue(queue* q) {
q->front = q->rear = 0;
}
// 判断队列是否为空
bool is_empty(queue* q) {
return q->front == q->rear;
}
// 入队
void enqueue(queue* q, node n) {
q->data[q->rear++] = n;
}
// 出队
node dequeue(queue* q) {
return q->data[q->front++];
}
// 判断点是否越界
bool is_out_of_range(int x, int y, int m, int n) {
return x < 0 || x >= m || y < 0 || y >= n;
}
// 判断点是否为通路
bool is_path(int x, int y) {
return maze[x][y] == 0;
}
// 判断点是否已经访问过
bool is_visited(int x, int y) {
return visited[x][y];
}
// 标记点已访问
void mark_visited(int x, int y) {
visited[x][y] = true;
}
// 搜索迷宫
node search_maze(int sx, int sy, int ex, int ey, int m, int n) {
// 初始化队列和访问数组
queue q;
init_queue(&q);
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
visited[i][j] = false;
}
}
// 将起点加入队列并标记为已访问
node start = {sx, sy, 0};
enqueue(&q, start);
mark_visited(sx, sy);
// 循环搜索直到队列为空
while (!is_empty(&q)) {
// 取出队列的首节点
node cur = dequeue(&q);
int x = cur.x;
int y = cur.y;
int step = cur.step;
// 如果当前节点为终点,则返回结果
if (x == ex && y == ey) {
return cur;
}
// 遍历上下左右四个方向的邻居节点
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (!is_out_of_range(nx, ny, m, n) && is_path(nx, ny) && !is_visited(nx, ny)) {
// 将邻居节点加入队列并标记为已访问
node next = {nx, ny, step + 1};
enqueue(&q, next);
mark_visited(nx, ny);
}
}
}
// 如果队列为空仍未找到终点,则返回一个空节点
node empty = {-1, -1, -1};
return empty;
}
int main() {
int m, n;
printf("请输入迷宫的行数和列数:");
scanf("%d%d", &m, &n);
printf("请输入迷宫(0表示通路,1表示障碍物):\n");
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
scanf("%d", &maze[i][j]);
}
}
int sx, sy, ex, ey;
printf("请输入起点和终点的坐标(从0开始):");
scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
node result = search_maze(sx, sy, ex, ey, m, n);
if (result.step == -1) {
printf("无解\n");
} else {
printf("最短路长度:%d\n", result.step);
}
return 0;
}
```
阅读全文