题目:迷宫求解问题
[问题描述]
设计一个8X8的迷宫, 迷宫入口为(1,1) ,出口为(8,8), 设计算法, (1)求出从入口到出口的所有可能路径。(2)求出从入口到出口的最短路径。
[基本要求]
(1) 用矩阵表示一个迷宫,并输出该迷宫;。
(2) 显示所有路径的移动轨迹。
1、使用的数据结构:主要用了顺序栈跟深度优先搜索寻找路径。
2、算法思想:要从(1,1)开始,所以先生成一个10X10矩阵,然后外围生成一圈不可走不输出,创建一个8X8的迷宫。用特定符号显示生成迷宫,然后开始用顺序栈来输出路径,以及用深度优先搜索来寻找路径,判断能走与不能走,然后每找到一次出口,就把栈内容输出一条路径,然后重新开始以输出全部路径跟移动轨迹。然后根据长度对比,找出最短路径输出。
#include<iostream>
using namespace std;
#define MaxSize 100
struct Queue
{
int x, y;//方块在迷宫中的坐标位置(i,j)
int pre;// 记录点扫到哪个方向 0123分别表示左右上下
};
int** mg; int m, n;//迷宫矩阵,以及长宽
Queue Stack[MaxSize]; //定义顺序非循环栈
Queue Path[MaxSize];//记住最小路径的走向
int min[MaxSize][MaxSize];//用来记住最小路径时的矩阵,以便输出画出路径
int top = 0; //top指针
int path_num = 1;//路径数
int minlen = MaxSize;//最短路径a once
void ShuMg();//输入迷宫
void CreatMg(int**& mg, int m, int n);//生成迷宫
void print_lujing();//输出一条路径
void Find_Path();//完成一次路径的行走
void Find_ShorestPath();//输出最短路径
void mg_path(int xi, int yi, int xe, int ye);//完成所有路径的行走,找出最短路径
void ShuMg()//输入迷宫
{
cout << "请输入迷宫的长和宽:" << endl;
cin >> m >> n;
mg = new int* [m + 2];//增加上下两个空间构建围墙
for (int i = 0; i <= m + 1; i++)
mg[i] = new int[n + 2];//增加左右两个空间构建围墙
cout << "请你输入迷宫矩阵(0/1)" << endl;
cout << "0代表可走,1代表墙壁不可走" << endl;
for (int a = 1; a <= m; a++)//输入迷宫矩阵
{
for (int b = 1; b <= n; b++)
{
cin >> mg[a][b];
if (mg[a][b] != 0 && mg[a][b] != 1)//定义只能输入0和1
{
cout << "输入有误!" << endl;
}
}
}
//设置迷宫外围为隐形的墙壁
for (int i = 0; i <= m + 1; i++)
mg[0][i] = 1;//上边
for (int i = 1; i <= n; i++)
{
mg[i][0] = 1;//左边
mg[i][n + 1] = 1;//下边
}
for (int i = 0; i <= m + 1; i++)
mg[n + 1][i] = 1;//右边
cout << "---------------------------------" << endl;
}
void CreatMg(int**& mg, int m, int n)//生成迷宫
{
cout << "-------------迷宫--------------" << endl;
cout << endl;
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
if (mg[i][j] == 0)cout << "□";//二维数组中为0的位置全部输出"□"
else cout << "×";//否则输出×
}
cout << endl;
}
}
void print_lujing()//输出一条路径
{
cout << endl;
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
if ((i == 1 && j == 1) || (i == m && j == n) || mg[i][j] == -1) cout << "★";
//(1,1)和(m,n)位置输出★
else if (mg[i][j] == 1) cout << "×";//定义输入1代表不可走
else cout << "□";
}
cout << endl;
}
cout << endl;
}
void Find_Path()//完成一次路径的行走
{
int k, h = 0;
cout << "第" << path_num << "条路径:Start->";
for (k = 1; k <= top; k++)//从栈里面取出(x,y)
{
cout << "(" << Stack[k].x << "," << Stack[k].y << ")" << "->";
h++;
if (h % 6 == 0) cout << endl;
}
cout << "End";
path_num++;//作为路径数计数器
cout << endl;
if (top + 1 < minlen)//比较长度然后把最小的给path[]
{
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
min[i][j] = mg[i][j];
for (k = 1; k <= top; k++)
Path[k] = Stack[k];
minlen = top + 1;
}
print_lujing();
}
void Find_ShorestPath()//输出最短路径
{
if (path_num == 1) { cout << "没有路"; exit(0); }//判断有没有路
int k, h = 0;
cout << "最短路径的长度为" << minlen - 1 << ",最短路径如下:" << endl;
cout << "start->";
for (k = 1; k < minlen; k++)//输出路径
{
cout << "(" << Path[k].x << "," << Path[k].y << ")" << "->";
h++;
if (h % 6 == 0) cout << endl;
}
cout << "end";
cout << endl;
for (int i = 1; i <= m; i++)//输出迷宫路径图
{
for (int j = 1; j <= n; j++)
{
if ((i == 1 && j == 1) || (i == m && j == n) || min[i][j] == -1) cout << "★";
else if (min[i][j] == 1) cout << "×";
else cout << "□";
}
cout << endl;
}
}
void mg_path(int xi, int yi, int xe, int ye)//完成所有路径的行走,找出最短路径
{
int i, j, i1, j1, di;
int flag;
top++; // 进栈
Stack[top].x = xi;
Stack[top].y = yi;
Stack[top].pre = -1;
mg[xi][yi] = -1; // 初始方块进栈
while (top > -1) // 栈不空时循环
{
i = Stack[top].x; j = Stack[top].y; // 取栈顶方块(i,j)
di = Stack[top].pre;
if (i == xe && j == ye) // 找到了出口
{
Find_Path(); // 输出一条路径
top--;
// 出口退栈,即回退一个方块
mg[i][j] = 0; // 让出口变为其他路径可走方块
i = Stack[top].x; j = Stack[top].y;
di = Stack[top].pre; // 让栈顶方块变为当前方块
}
flag = 0; // 找下一个可走方块(i1,j1);
while (di < 4 && !flag)//寻找路径
{
di++;
switch (di)//前一点走的方向
{
case 0:i1 = i - 1; j1 = j; break;//左
case 1:i1 = i; j1 = j + 1; break;//右
case 2:i1 = i + 1; j1 = j; break;//上
case 3:i1 = i; j1 = j - 1; break;//下
}
if (mg[i1][j1] == 0)flag = 1;
}
if (flag) // 找到了下一个可走方块(i1,j1)
{
Stack[top].pre = di; // 修改原栈顶元素的di值
top++; Stack[top].x = i1, Stack[top].y = j1;
Stack[top].pre = -1; // 下一个可走方块(i1,j1)进栈
mg[i1][j1] = -1; // 避免重复走到该方块
}
else // 没有路径可走,则(i,j)方块退栈
{
mg[i][j] = 0; // 让该位置变为其他路径可走方块
top--;
}
}
Find_ShorestPath(); // 输出最短路径
}
int main()
{
ShuMg();
CreatMg(mg, m, n);
mg_path(1, 1, m, n);
system("pause");
return 0;
}
运行结果较多这里就不列出来了,可以直接复制代码运行