数据结构课设迷宫问题

2023-12-27 18:43:32

迷宫问题

【问题描述】以一个m×n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。

【基本要求】编写一个求解迷宫的非递归程序。求得的通路以三元组(i,j,d)的形式输出,其中:(i,j)指示迷宫中的一个坐标,d表示走到下一坐标的方向。如:对于下列数据的迷宫,输出的一条通路为z(1,1,1),(1,2,2),(2,2,2),(3,2,3),(3,1,2),··。

【测试数据】迷宫的测试数据如下:左上角(1,1)为入口,右下角(8,9)为出口。

???????????????1 ???2 ???3 ???4 ???5 ???6 ???7 ???8

0

0

1

0

0

0

1

0

0

0

1

0

0

0

1

0

0

0

0

0

1

1

0

1

0

1

1

1

0

0

1

0

0

0

0

1

0

0

0

0

0

1

0

0

0

1

0

1

0

1

1

1

1

0

0

1

1

1

0

0

0

1

0

1

1

1

0

0

0

0

0

0

【实现提示】计算机解迷宫通常用的是“穷举求解“方法,即从入口出发,顺着某一个方向进行探索,若能走通,则继续往前进;否则沿着原路退回,换一个方向继续探索,直至出口位置,求得一条通路。假如所有可能的通路都探索到而未能到达出口,则所设定的迷宫没有通路。

可以二维数组存储迷宫数据,通常设定入口点的下标为(1,1),出口点的下标为(n,n)。为处理方便起见,可在迷宫的四周加一圈障碍。对于迷宫中任一位置,均可约定有东、南、西、北四个方向可通。

【选作内容】注:可参考教材50页

(l) 编写递归形式的算法,求得迷宫中所有可能的通路;

(2) 以方阵形式输出迷宫及其通路。

#include <stdio.h>
#include <malloc.h>
#include <pthread.h>
#include <unistd.h>
#define M 10
#define N 10 // 测试案例1,2
// #define M 12
// #define N 12 // 测试案例3
typedef struct
{ // 通路记录
    int current_x;
    int current_y;
    int di;
} Box;
typedef struct sNode
{ // 链栈定义
    Box box;
    struct sNode *next;
} *Linkstack;
void push(Linkstack &top, Box box)
{ // 入栈函数
    Linkstack p;
    p = (Linkstack)malloc(sizeof(struct sNode));
    p->box = box;
    p->next = top;
    top = p;
}
Box pop(Linkstack &top)
{
    Linkstack p = top; // 保存当前栈顶节点
    top = top->next;   // 栈顶指针指向下一个节点
    Box box = p->box;  // 获取出栈元素

    free(p); // 释放出栈节点内存空间

    return box;
}

bool isEmpty(Linkstack &top)
{
    if (top == NULL)
    {
        return true;
    }
    else
    {
        return false;
    }
}
void print_stack(Linkstack top)
{
    Linkstack p;
    p = top;
    while (p)
    {
        printf("(%d,%d,%d)\n", p->box.current_y, p->box.current_x, p->box.di);
        p = p->next;
    }
}
void print_maze(int maze[M][N])
{
    for (int i = 0; i < M; i++)
    {
        for (int j = 0; j < N; j++)
        {
            if (maze[i][j] == 1)
            {
                printf("■ ");
            }
            if (maze[i][j] == -1)
            {
                printf("★ ");
            }
            if (maze[i][j] == 0)
            {
                printf("□ ");
            }
            if (maze[i][j] == -2)
            {
                printf("○ ");
            }
        }
        printf("\n");
    }
    printf("--------------------\n");
    sleep(1.5);
}
bool DFS(int maze[M][N], int direction[][2], Linkstack &top, Box end, Box temp)
{
    int current_x, current_y, current_di; // 当前坐标
    int next_x, next_y;                   // 下一个位置的坐标
    maze[temp.current_y][temp.current_x] = -1;
    push(top, temp);
    while (!isEmpty(top))
    {
        temp = pop(top);
        current_x = temp.current_x;
        current_y = temp.current_y;
        current_di = temp.di + 1;
        while (current_di < 4)
        {
            next_x = current_x + direction[current_di][0]; // 确定下个位置的x坐标
            next_y = current_y + direction[current_di][1]; // 确定下个位置的y坐标

            if (maze[next_y][next_x] == 0)
            { // 判断下个位置坐标是否可走
                maze[next_y][next_x] = -1;
                temp.current_x = current_x;
                temp.current_y = current_y;
                temp.di = current_di; // 将当前方向保存
                push(top, temp);      // 入栈
                // print_maze(maze);
                current_x = next_x; // 更新坐标
                current_y = next_y; // 更新坐标
                current_di = 0;
                if (current_x == end.current_x && current_y == end.current_y)
                { // 到达终点
                    temp.current_x = current_x;
                    temp.current_y = current_y;
                    temp.di = current_di; // 将当前方向保存
                    push(top, temp);      // 入栈
                    return true;
                }
            }
            else
            {
                current_di++; // 更换方向
            }
        }
        if (current_di == 4 && maze[current_y][current_x] == -1) // 当前坐标已走完且无通路
        {
            maze[current_y][current_x] = -2;
        }
    }
    return false;
}
void RecursionDFS(int maze[M][N], int direction[][2], Linkstack &top, Box current, Box end)
{
    if (current.current_x == end.current_x && current.current_y == end.current_y)
    {
        printf("这是一条路径\n");
        print_stack(top);
        print_maze(maze);
        printf("============================\n");
        return;
    }
    for (int i = 0; i < 4; i++)
    {
        if (maze[current.current_y][current.current_x] == 0)
        { // 将起点进栈
            maze[current.current_y][current.current_x] = -1;
        }

        int next_x = current.current_x + direction[i][0];
        int next_y = current.current_y + direction[i][1];
        if (maze[next_y][next_x] == 0)
        {

            maze[next_y][next_x] = -1;
            Box temp;
            temp.current_x = next_x;
            temp.current_y = next_y;
            current.di = i;                                //!!!!!!!,记录当前要存入栈中位置的指向下一个位置的方向
            push(top, current);                            // 存入当前位置,以及当前指向下一个位置的方向
            RecursionDFS(maze, direction, top, temp, end); // 传入的temp是自己本身的坐标,不是下一个位置的坐标
            maze[next_y][next_x] = 0;
            pop(top);
        }
    }
}
int main()
{
    Linkstack top = NULL;
    int direction[][2] = {{0, -1}, {1, 0}, {0, 1}, {-1, 0}}; // 方位数组,上右下左
    int maze[M][N] = {                                       // 测试案例1,M,N都为10
                      {1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
                      {1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
                      {1, 0, 1, 1, 1, 1, 1, 1, 1, 1},
                      {1, 0, 1, 0, 0, 0, 0, 0, 0, 1},
                      {1, 0, 0, 0, 1, 1, 1, 1, 0, 1},
                      {1, 0, 1, 0, 1, 0, 0, 0, 0, 1},
                      {1, 0, 1, 0, 1, 1, 1, 1, 0, 1},
                      {1, 0, 1, 0, 0, 0, 0, 0, 0, 1},
                      {1, 1, 1, 1, 1, 1, 1, 1, 0, 1},
                      {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}};
    //       int maze[M][N] = {                                       // 测试案例2,M,N都为10,无通路
    //   {1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
    //   {1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
    //   {1, 0, 1, 1, 1, 1, 1, 1, 1, 1},
    //   {1, 0, 1, 0, 0, 0, 0, 0, 0, 1},
    //   {1, 0, 0, 0, 1, 1, 1, 1, 0, 1},
    //   {1, 0, 1, 0, 1, 0, 0, 0, 0, 1},
    //   {1, 0, 1, 0, 1, 1, 1, 1, 1, 1},
    //   {1, 0, 1, 1, 0, 0, 0, 0, 0, 1},
    //   {1, 1, 1, 1, 1, 1, 1, 1, 0, 1},
    //   {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}};
    // int maze[M][N] = {
    //     {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, // 测试案例3,M,N都为12
    //     {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
    //     {1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1},
    //     {1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1},
    //     {1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1},
    //     {1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1},
    //     {1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1},
    //     {1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1},
    //     {1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1},
    //     {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1},
    //     {1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1},
    //     {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}};
    bool is = DFS(maze, direction, top, Box{8, 8, 0}, Box{1, 1, -1}); // 测试案例1
    // bool is = DFS(maze, direction, top, Box{8, 8, 0}, Box{1,1,-1});//测试案例2
    // bool is = DFS(maze, direction, top, Box{10, 10, 0}, Box{1, 1, -1});//测试案例3
    if (is)
    {
        printf("找到路径\n");
        print_stack(top);
        print_maze(maze);
    }
    else
    {
        printf("没有找到路径\n");
    }
    // RecursionDFS(maze, direction, top, Box{1, 1, 0}, Box{8, 8, 0}); // 递归求全路径,测试案例1,2
    //    RecursionDFS(maze, direction, top, Box{1, 1, 0}, Box{8, 8, 0}); // 递归求全路径,测试案例1,2
    // RecursionDFS(maze, direction, top, Box{1, 1, 0}, Box{10, 10, 0}); // 递归求全路径,测试案例3
    return 0;
}

文章来源:https://blog.csdn.net/format_push/article/details/135252037
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。