为期一周的数据结构课程设计中写了一个迷宫问题的C++程序,虽然迷宫问题的程序已经很多人贴出来过了,程序也非常地简单,但是只要查过一遍就能发现大多数都是简单的深度优先搜索求一条路径,或者是广度优先搜索遍历求最短路径,之所以很少有求迷宫入口到出口之间所有路径的程序,是因为这样做本身就显得没有必要。若是设计一个走迷宫的小游戏,只要验证玩家给出的路径是否能走通就可以了,若有多条路径可以直接用广度优先搜索来给出最短路径作为答案
但是为了课程设计能得到更高的分数,所以另辟蹊径,先求出入口到出口之间的所有路径,再从所有路径中比较得出最短路径。两点之间求多条路径的程序也不是没有过,没错,就是借鉴图结构两点之间求多条路径的方法,主要思想是利用栈和深度优先搜索
以下是求解的迷宫图:
详细设计框架:
结构体MapPoint设计:设置两个整形数据成员x和y来表示迷宫中某个点的坐标,成员函数MapPoint way(int direct)根据传入的数字0-7返回相对于当前坐标八个不同方向的点
栈Stack设计:
类Maze设计:
源代码:
头文件 标头.h:
//Maze.h
#include
using namespace std;
#define MAX 80
struct MapPoint{ //迷宫点结构体,栈元素类型
int x;
int y;
MapPoint move(int direct); 分别返回相对于当前位置八个方向的点
};
MapPoint MapPoint::move(int direct)
{
switch (direct)
{
case 0://上
{
MapPoint t = { x,y + 1 };
return t;
}
case 1://下
{
MapPoint t = { x,y - 1 };
return t;
}
case 2://左
{
MapPoint t = { x - 1,y };
return t;
}
case 3://右
{
MapPoint t = { x + 1,y };
return t;
}
case 4://左上
{
MapPoint t = { x - 1,y + 1 };
return t;
}
case 5://左下
{
MapPoint t = { x - 1,y - 1 };
return t;
}
case 6://右上
{
MapPoint t = { x + 1,y + 1 };
return t;
}
case 7://右下
{
MapPoint t = { x + 1,y - 1 };
return t;
}
default:
cout << endl << "输入选项错误!";
}
}
class Stack { //栈定义
int top;
MapPoint s[MAX];
int minitop;
MapPoint minipath[MAX];
public:
Stack() //空栈构造函数
{top = -1; minitop = MAX - 1;}
bool IsEmpty() { //栈空判定
if (top == -1)
return 1;
else
return 0;
}
bool push(MapPoint a) { //入栈
if (top == MAX - 1)
{
cout << endl << "栈已满!";
return 0;
}
else {
top++;
s[top].x = a.x;
s[top].y = a.y;
return 1;
}
}
bool pop() { //出栈
if (IsEmpty()) { return 0; }
else { top--; return 1; }
}
MapPoint GetTop() { //取栈顶元素
if (top != -1)
return s[top];
else //栈空则返回起点的坐标
{
MapPoint t;
t.x = 1; t.y = 1;
return t;
}
}
void Display() { //从栈尾依次输出栈元素,即输出迷宫通路
if (minitop > top) //每次输出路径前尝试修改保存的最短路径
{
minitop = top;
for (int i = 0; i <= top; i++)
minipath[i] = s[i];
}
cout << endl;
cout << endl << "找到路径如下:";
for (int i = 0; i<=top; i++)
{
cout << '(' << s[i].x << "," << s[i].y << ')';
if (i != top)
cout << "->";
}
}
bool Shortest() //输出最短路径
{
cout << endl;
if (minitop == MAX - 1)
{
cout << endl << "找不到入口与出口间的通路,故无最短路径!";
return 0;
}
else
{
cout << endl << "最短路径如下:";
for (int i = 0; i <= minitop; i++)
{
cout << '(' << minipath[i].x << "," << minipath[i].y << ')';
if (i != minitop)
cout << "->";
}
minitop = MAX - 1; //输出一遍后重置
return 1;
}
}
};
class Maze {
int been[8][10]; //用做标记走过的点
int MazeMap[8][10]; //迷宫地图定义
public:
Maze(); //构造函数
bool Pass(MapPoint p); //判断某点是否可以走
void MultiPath(MapPoint Out, Stack &a); //寻找和输出所有路径和标出最短路径
void MazeOutput(); //输出迷宫地图
void Interact(); //用户交互函数
};
Maze::Maze() //所有标志置0,定义迷宫地图
{
int i, j;
for (i = 0; i < 8; i++)
for (j = 0; j < 10; j++)
been[i][j] = 0;
int map[8][10]={
{ 1,1,1,1,1,1,1,1,1,1 },
{ 1,0,1,1,1,0,1,1,1,1 },
{ 1,1,0,1,0,1,1,1,1,1 },
{ 1,0,1,0,0,0,0,0,1,1 },
{ 1,0,1,1,1,0,1,1,1,1 },
{ 1,1,0,0,1,1,0,0,0,1 },
{ 1,0,1,1,0,0,1,1,0,1 },
{ 1,1,1,1,1,1,1,1,1,1 }
};
for (i = 0; i < 8; i++)
for (j = 0; j < 10; j++)
MazeMap[i][j] = map[i][j];
}
bool Maze::Pass(MapPoint p) { //成员函数pass定义
if (p.x<0 || p.x>7) { //x坐标超出迷宫范围
return 0;
}
else if (p.y<0 || p.y>9) { //y坐标超出迷宫范围
return 0;
}
else if (been[p.x][p.y] == 1) {//前面已经走过该点
return 0;
}
else if (MazeMap[p.x][p.y] == 1){//该点是障碍
return 0;
}
else return 1; //可以走
}
void Maze::MultiPath(MapPoint Out, Stack &a) //成员函数MultiPath定义
{
MapPoint l = a.GetTop();
if (l.x == Out.x&&l.y == Out.y) { //栈顶元素为出口则输出当前路径
a.Display(); //后回退(取标出栈)并结束函数调用
been[l.x][l.y] = 0;
a.pop();
return;
}
for (int i = 0; i < 8; i++) //循环遍历探测周围方向上的点
{ //保证递归返回到分叉点时不再选择已选方向
if (Pass(l.move(i)))
{
MapPoint m = l.move(i);
been[m.x][m.y] = 1;
a.push(m);
MultiPath(Out, a);
}
}
if (a.pop()) //该分叉点已探测完所有选项,出栈成功则取标回退
been[l.x][l.y] = 0;
if (a.IsEmpty())
if(a.Shortest())
cout << endl << "所有路径及最短路径输出完毕!"; //栈空表明再无分支
}
void Maze::MazeOutput() //成员函数MazeOutput定义
{
cout << "迷宫图如下:" << endl;
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 10; j++)
{
cout << MazeMap[i][j] << " ";
}
cout << endl;
}
}
void Maze::Interact() //成员函数interact定义
{
char answer;
MapPoint Out, In; //定义出口和人口
Stack a;
MazeOutput();
while (true)
{
cout << endl << "你想知道该迷宫某两点之间的所有路径和最短路径吗?";
cout << endl << "回答是或否(输入Y/N),输入迷宫入口和出口获悉路径或退出程序:";
cin >> answer;
if (answer == 'Y' || answer == 'y') //MultiPath调用完后所有标记由于回退会被清除
{
cout << endl << "请输入入口坐标:";
cin >> In.x >> In.y;
cout << endl << "请输入出口坐标:";
cin >> Out.x >> Out.y;
been[In.x][In.y] = 1;
a.push(In); //将入口入栈
MultiPath(Out, a);
cout << endl;
}
else if (answer == 'N' || answer == 'n')
break;
else
cout << endl << "输入数据无效,请重新输入有效数据回答该问题!";
}
}
源文件 源.cpp :
//Maze.cpp
#include"标头.h"
int main()
{
Maze m;
m.Interact();
system("pause");
return 0;
}
设计特色:先求所有路径,再比较得出最短路径;地图存储在二维数组内,不必手动输入,运行直接显示全地图;将迷宫及其操作函数整合为一个类,模块化编程
详细课程设计报告链接:https://wenku.baidu.com/view/89cae68bf605cc1755270722192e453610665bde