凯H 2023-06-05 12:17 采纳率: 81%
浏览 27

这段迷宫问题的C语言代码有问题吗


#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ROWS 20
#define COLS 20

// 判断坐标是否越界
int is_out_of_bounds(int row, int col) {
    return row < 0 || row >= ROWS || col < 0 || col >= COLS;
}

// 判断当前坐标的位置是否为障碍
int is_obstacle(int maze[ROWS][COLS], int row, int col) {
    return maze[row][col] == 1;
}

// 定义队列节点数据结构
typedef struct {
    int row;
    int col;
    int steps;
} Position;

// 创建一个队列节点并初始化
Position* createPos(int x, int y, int steps) {
    Position* pos = (Position*)malloc(sizeof(Position));
    pos->row = x;
    pos->col = y;
    pos->steps = steps;
    return pos;
}

// 定义队列数据结构
typedef struct {
    Position* data;
    int size;
    int maxSize;
    int front;
    int rear;
} Queue;

// 初始化队列
Queue* initQueue(int maxSize) {
    Queue* q = (Queue*)malloc(sizeof(Queue));
    q->data = (Position*)malloc(sizeof(Position) * maxSize);
    q->size = 0;
    q->maxSize = maxSize;
    q->front = 0;
    q->rear = -1;
    return q;
}

// 判断队列是否为空
int isQueueEmpty(Queue* q) {
    return q->size == 0;
}

// 队列添加节点
void enqueue(Queue* q, Position* pos) {
    if (q->size >= q->maxSize) {
        printf("Queue is full.\n");
        return;
    }
    q->rear++;
    if (q->rear == q->maxSize) {
        q->rear = 0;
    }
    q->data[q->rear] = *pos;
    q->size++;
}

// 队列弹出节点
Position* dequeue(Queue* q) {
    if (isQueueEmpty(q)) {
        printf("Queue is empty.\n");
        return NULL;
    }
    Position* temp = &(q->data[q->front]);
    q->front++;
    if (q->front == q->maxSize) {
        q->front = 0;
    }
    q->size--;
    return temp;
}

// 释放队列
void freeQueue(Queue * q) {
    free(q->data);
    free(q);
}

// 打印迷宫
void print_maze(int maze[ROWS][COLS]) {
    for (int i = 0; i < ROWS; ++i) {
        for (int j = 0; j < COLS; ++j) {
            if (maze[i][j] == 0) {
                printf(" ");
            } else {
                printf("#");
            }
        }
        printf("\n");
    }
}

// 初始化迷宫
void init_maze(int maze[ROWS][COLS]) {
    for (int i = 0; i < ROWS; ++i) {
        for (int j = 0; j < COLS; ++j) {
            maze[i][j] = 1;
        }
    }
}

// 随机生成迷宫
void generate_maze(int maze[ROWS][COLS], int start_row, int start_col) {
    srand(time(NULL));
    maze[start_row][start_col] = 0;
    Queue* q = initQueue(ROWS*COLS);
    enqueue(q, createPos(start_row, start_col, 0));
    int directions[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
    while (!isQueueEmpty(q)) {
        Position* current = dequeue(q);
        int x = current->row;
        int y = current->col;
        int steps = current->steps;
        free(current);
        for (int i = 0; i < 4; ++i) {
            int dx = directions[i][0];
            int dy = directions[i][1];
            int nx = x + dx * 2;
            int ny = y + dy * 2;
            if (!is_out_of_bounds(nx, ny) && is_obstacle(maze, nx-dx, ny-dy) &&is_obstacle(maze, nx, ny)) {
                maze[nx-dx][ny-dy] = 0;
                maze[nx][ny] = 0;
                enqueue(q, createPos(nx, ny, steps+1));
            }
        }
    }
    freeQueue(q);
}

// 广度优先搜索
void bfs(int maze[ROWS][COLS], int start_row, int start_col, int end_row, int end_col) {
    Queue* q = initQueue(ROWS*COLS);
    int visited[ROWS][COLS] = {0};
    visited[start_row][start_col] = 1;
    enqueue(q, createPos(start_row, start_col, 0));
    int found = 0;
    int directions[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
    while (!isQueueEmpty(q)) {
        Position* current = dequeue(q);
        int x = current->row;
        int y = current->col;
        int steps = current->steps;
        free(current);
        for (int i = 0; i < 4; ++i) {
            int dx = directions[i][0];
            int dy = directions[i][1];
            int nx = x + dx;
            int ny = y + dy;
            if (!is_out_of_bounds(nx, ny) && !visited[nx][ny] && !is_obstacle(maze, nx, ny)) {
                visited[nx][ny] = 1;
                enqueue(q, createPos(nx, ny, steps+1));
                if (nx == end_row && ny == end_col) {
                    printf("Found the path with %d steps.\n", steps+1);
                    found = 1;
                    break;
                }
            }
        }
        if (found) {
            break;
        }
    }
    freeQueue(q);
    if (!found) {
        printf("Path not found.\n");
    }
}

int main() {
    int maze[ROWS][COLS];
    init_maze(maze);
    generate_maze(maze, 0, 0);
    printf("Maze:\n");
    print_maze(maze);
    printf("Finding the shortest path from top-left corner to bottom-right corner:\n");
    bfs(maze, 0, 0, ROWS-1, COLS-1);
    return 0;
}
  • 写回答

2条回答 默认 最新

  • 憧憬blog 2023-06-05 14:16
    关注

    这段C语言代码的语法没有问题,但是可能存在逻辑问题或者效率问题。以下是对代码的一些评价和建议:

    1. 这段代码的主要功能是生成一个迷宫,并在迷宫中找到从左上角到右下角的最短路径。

    2. 生成迷宫的过程使用了随机算法,这是一种比较有效的方法,但是生成的迷宫可能不一定是连通的,也就是说有些区域可能无法到达,因此可能会导致找不到路径的情况。如果希望生成的迷宫是连通的,可以使用其他算法,例如深度优先搜索。

    3. 广度优先搜索是一种有效的方法来寻找最短路径,但是这段代码中的实现有一些问题。例如,为了避免重复访问已经访问过的节点,使用了一个visited数组来记录节点的访问状态。但是在迷宫中,障碍物的位置不能被访问,因此visited数组的初始值应该是障碍物位置为1,其他位置为0。另外,在扩展节点时,应该先判断当前节点是否是目标节点,如果是目标节点就直接返回,这样可以减少不必要的遍历。

    4. 在使用队列时,应该考虑队列溢出的情况。这段代码中使用了一个maxSize变量来记录队列的最大容量,但是在实际使用时,如果队列已经满了,就会出现队列溢出的情况。可以考虑将队列容量动态调整,或者使用链表队列等数据结构。

    5. 在释放队列时,应该先释放队列中保存的节点,然后再释放队列本身。这段代码中的释放顺序是反过来的,可能会导致内存泄漏。

    6. 在定义队列节点数据结构时,可以将x和y改成row和col,这样更符合语义。

    7. 在判断当前坐标的位置是否为障碍时,可以使用maze[row][col] != 0代替maze[row][col] == 1,这样更简洁。

    8. 在判断队列是否为空时,可以直接返回q->front == q->rear,这样更简洁。

    评论

报告相同问题?

问题事件

  • 创建了问题 6月5日

悬赏问题

  • ¥15 系统 24h2 专业工作站版,浏览文件夹的图库,视频,图片之类的怎样删除?
  • ¥15 怎么把512还原为520格式
  • ¥15 MATLAB的动态模态分解出现错误,以CFX非定常模拟结果为快照
  • ¥15 求高通平台Softsim调试经验
  • ¥15 canal如何实现将mysql多张表(月表)采集入库到目标表中(一张表)?
  • ¥15 wpf ScrollViewer实现冻结左侧宽度w范围内的视图
  • ¥15 栅极驱动低侧烧毁MOSFET
  • ¥30 写segy数据时出错3
  • ¥100 linux下qt运行QCefView demo报错
  • ¥50 F1C100S下的红外解码IR_RX驱动问题