迷宫
集美大学课程实验报告-走迷宫
项目名称 | 使用队列和栈实现迷宫 |
---|---|
课程名称 | 数据结构 |
班级 | 网安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.队列写法
![本机截图]
五、实验小结(实验中遇到的问题及解决过程、实验体会和收获)
以下请根据实际情况编写
遇到的问题及解决方法:
- 问题:程序崩溃找不到原因,
- 解决方法:使用打断点进行调试的方法。
2.问题:只用一个栈没办法保存正确路径并输出 - 解决方法:使用两个栈,一个为临时栈,一个为输出栈
实验体会和收获:
- 学会了如何搭建C++开发环境。
- 掌握了基本的代码调试方法。
- 掌握了Visual Studio调试功能的基本使用