迷宫

集美大学课程实验报告-走迷宫

项目名称 使用队列和栈实现迷宫
课程名称 数据结构
班级 网安2413、网安2412
指导教师 郑如滨
学生姓名 林沁茹、李秀清
学号 202421336067,2024213336039
实验项目名称 走迷宫
上机实践日期
上机实践时间 2学时

一、目的(本次实验所涉及并要求掌握的知识点)

以下内容请根据实际情况编写

  • 掌握栈和队列相关用法
  • 使用栈走迷宫
  • 使用队列走迷宫

二、实验内容与设计思想

题目1:栈的迷宫应用(李秀清)

函数相关伪代码

1.设定迷宫路径,输入起点和终点
2.定义一个结构体来储存迷宫的位置
3.用一个临时栈来储存路径,以便回溯,用路径栈以便输出。
4.判断是否能到达终点,如果可以则输出路径

函数代码

#include <iostream>
#include <stack>

using namespace std;

// 定义一个结构体来存储迷宫中的位置
struct Position {
    int x, y;
    Position(int x, int y) : x(x), y(y) {}
};

bool solveMaze(int maze[10][10], Position start, Position end, stack<Position>& path) {
    const int rows = 10;
    const int cols = 10;
    bool visited[10][10] = { false };
    stack<Position> stk;
    stack<Position> tempPath; // 临时栈用于存储路径

    stk.push(start);
    visited[start.x][start.y] = true;

    int directions[4][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };

    while (!stk.empty()) {
        Position current = stk.top();
        stk.pop();
        tempPath.push(current); // 将当前位置压入临时路径栈

        if (current.x == end.x && current.y == end.y) {
            // 找到终点,将临时路径栈的路径复制到路径栈中
            while (!tempPath.empty()) {
                path.push(tempPath.top());
                tempPath.pop();
            }
            return true;
        }

        for (int i = 0; i < 4; ++i) {
            int nx = current.x + directions[i][0];
            int ny = current.y + directions[i][1];

            if (nx >= 0 && nx < rows && ny >= 0 && ny < cols && maze[nx][ny] == 0 && !visited[nx][ny]) {
                visited[nx][ny] = true;
                stk.push(Position(nx, ny));
            }
        }
    }
    return false;
}

int main() {
    int maze[10][10] = {
        {0, 0, 0, 1, 1},
        {0, 1, 1, 1, 0},
        {0, 0, 0, 1, 0},
        {1, 1, 0, 0, 1},
        {0, 0, 1, 0, 0}
    };
    Position start(0, 0);
    Position end(4, 4);
    stack<Position> path;

    if (!solveMaze(maze, start, end, path)) {
        cout << "No path found!" << endl;
    }
    else {
        cout << "Path found!" << endl;
        // 输出路径
        while (!path.empty()) {
            Position pos = path.top();
            path.pop();
            cout << "(" << pos.x << ", " << pos.y << ") ";
        }
        cout << endl;
    }
    return 0;
}

题目2:队列的迷宫应用(林沁茹)

函数相关伪代码

1.输入迷宫(map[a][s])
2.起点(m,n),终点(m1,n1)
3.判断起点与终点是否可行
4.定义结构,路径(x,y),a{1,2,3,4}尝试过的方向,b来的方向
5.队列q存储结构
6.都试过返回上一格,尝试没走过的方向,不断循环
7.if(到终点)退出,输出队列
else 输出没找到

函数代码

#include <iostream>
#include <queue>
#include <vector>
using namespace std;
typedef struct {
    int x; // x 坐标
    int y; // y 坐标
    int a;//探索过的方向
    int b;//从哪来
} Box;
void showbase(queue<Box>& q,int m,int n) {
    Box a;
    while (!q.empty()) {
        a = q.front();
        cout << "(" << a.x << "," << a.y << ")"<<endl;
        q.pop();
    }
    cout << "(" << m << "," << n << ")";
}

void road(queue<Box>& q, int m, int n, int m1, int n1, int j, int k, vector<vector<int>>& map) {
    Box now = { m, n,0 },t;
   vector<vector<int>>p(j,vector<int>(k,0));
    int e, r,i=0;
    while (now.x<=m1 && now.y<=n1 && now.x >= 0 && now.y >= 0) {
        e = now.x;
        r = now.y;
        // 出队
        if (now.x == m1 && now.y == n1) {
            cout << "到达终点" << endl;
            showbase(q,m1,n1);
            return;
        }
        else {
            // 检查四个方向
            if (now.x - 1 >= 0&&now.a==0&&now.b!=now.a+1&&p[now.x-1][now.y]==0) {
                if (map[now.x - 1][now.y] == 1) {
                    now.a = 1;//上
                    p[now.x][now.y]=1;
                    q.push(now);
                    now.x = now.x - 1;
                    now.b = 3;
                    now.a = -1;
                    i++;
                }
                else {
                    now.a = 1;
                }
            }
             if (now.a == 1&& now.y - 1 >= 0 && now.b != now.a+1&&p[now.x][now.y-1]==0 ) {
                if (map[now.x][now.y-1] == 1) {
                    now.a = 2;//左
                    p[now.x][now.y]=1;
                    q.push(now);
                    now.y = now.y - 1;
                    now.b = 4;
                    now.a = -1;
                    i++;
                }
                else {
                    now.a = 2;
                }
            }
             if ( now.a == 2&& now.x + 1 <j && now.b != now.a+1&&p[now.x+1][now.y]==0) {
                if (map[now.x+1][now.y] == 1) {
                    now.a = 3;//下
                    p[now.x][now.y]=1;
                    q.push(now);
                    now.x = now.x + 1;
                    now.b = 1;
                    now.a = -1;
                    i++;
                }
                else {
                    now.a = 3;
                }
            }
            if ( now.a == 3&& now.y + 1 <k && now.b != now.a+1 &&p[now.x][now.y+1]==0) {
                if (map[now.x][now.y+1] == 1) {
                    now.a = 4;//右
                    p[now.x][now.y]=1;
                    q.push(now);
                    now.y = now.y + 1;
                    now.b = 2;
                    now.a = -1;
                    i++;
                }
                else {
                    now.a = 4;
                }
            }
            if (e == now.x && r == now.y && now.a == 4 &&now.b != now.a + 1 ) {
                if (!q.empty()) {
                    while (k < i) {
                        t = q.front();
                        q.push(t);
                        q.pop();
                        k++;
                    }
                   t = q.front();
                   p[t.x][t.y]=0;
                   q.pop();
                   if (!q.empty()) {
                        t = q.front();
                        p[t.x][t.y]=0;
                        q.pop();
                    }
                    if (t.a < 4) {
                        t.a++;
                    }
                    now.x = t.x;
                    now.y = t.y;
                    now.a = t.a;
                }
            }
        }
        if (now.a < 5) {
            now.a++;
        }
        else{
            break;
        }
    }
    cout << "无法到达终点" << endl;
}
int main() {
    int m, n; // 起点
    int m1, n1; // 终点
    int j, k; // 地图大小
    cout << "输入地图大小";
    cin >> j >> k;
    vector<vector<int>> map(j, vector<int>(k));
    cout << "输入地图(0表示不通,1表示通)";
    for (int i = 0; i < j; ++i) {
        cout << endl;
        for (int l = 0; l < k; ++l) {
            cin >> map[i][l];
        }
    }
    queue<Box> q;
    cout << "输入起点";
    cin >> m >> n;
    if (m >= j || n >= k || map[m][n] == 0) {
        cout << "输入错误,请重新输入起点";
        cin >> m >> n;
    }
    cout << "输入终点";
    cin >> m1 >> n1;
    if (m1 >= j || n1 >= k || map[m1][n1] == 0) {
        cout << "输入错误,请重新输入终点";
        cin >> m1 >> n1;
    }
    if (m1 < j && n1 < k && m < j && n < k && map[m][n] != 0 && map[m1][n1] != 0) {
        road(q, m, n, m1, n1, j, k, map);
    }
    return 0;
}




三、实验使用环境(本次实验所使用的平台和相关软件)

以下请根据实际情况编写

  • 操作系统:Windows 11 专业版
  • 编程语言:C++
  • 开发工具Visual Studio 2022

四、实验步骤和调试过程(实验步骤、测试数据设计、测试结果分析)

以下请根据实际情况编写

题目1:区间删除(符号配对)

本机运行截图
1.栈写法
![本机截图]

2.队列写法
![本机截图]


五、实验小结(实验中遇到的问题及解决过程、实验体会和收获)

以下请根据实际情况编写

遇到的问题及解决方法:

  1. 问题:程序崩溃找不到原因,
  • 解决方法:使用打断点进行调试的方法。
    2.问题:只用一个栈没办法保存正确路径并输出
  • 解决方法:使用两个栈,一个为临时栈,一个为输出栈

实验体会和收获:

  • 学会了如何搭建C++开发环境。
  • 掌握了基本的代码调试方法。
  • 掌握了Visual Studio调试功能的基本使用

总结议题:写栈和队列的对比

-栈是一种特殊的线性表,可以把它形象地看为一个箱子,限制在一端插入和删除。特点为先进后出。在迷宫的应用中使用两个栈,一个栈用于临时存储,另一个用于储存路径。相比而言,使用栈来解决迷宫问题空间复杂度会更大一些,但时间复杂度会小一些。
-队列是一种特殊的线性表,一端只能输入,一端只能输出,遵守先进先出原则。使用一个队列进行储存路径,对比栈,时间复杂度更大,空间复杂度较小

六、附件(参考文献和相关资料)

posted @ 2025-03-24 22:25  穗和  阅读(19)  评论(0)    收藏  举报