您的位置:首页 > 其它

栈的应用——求解迷宫问题

2017-06-13 11:31 316 查看
问题描述:

给定一个M×N的迷宫图,求一条从指定入口到出口的路径。假设迷宫图如图所示(M=10,N=10),其中的方块图表示迷宫。对于图中的每个方块,用空白表示通道,用阴影表示墙。要求所求路径必须是简单路径,即在求得的路径上不能重复出现同一通道块。




数据组织:为了表示迷宫,设置一个数组a,其中每个元素表示一个方块的状态,为0时表示对应方块是通道,为1时表示对应方块不可走。为了算法方便,在一般的迷宫外围加了一条围墙。



代码示例:

#include <iostream>
using namespace std;
const int MaxSize = 20;				//迷宫最大行、列数
const int StackSize = 100;			//顺序栈大小
struct Box							//方块结构体类型
{
int i;							//方块的行号
int j;							//方块的列号
int di;							//di是下一可走相邻方位的方位号
};
class Stack							//顺序栈类
{
Box *data;						//存放栈中方块
int top;						//栈顶指针
public:
Stack()							//构造函数:栈初始化
{
data = new Box[StackSize];
top = -1;
}
~Stack()						//析构函数:释放栈空间
{
delete[] data;
}
bool StackEmpty()				//判断栈是否为空
{
return(top == -1);
}
void Push(int x, int y, int d)	//进栈一个方块
{
top++;
data[top].i = x; data[top].j = y; data[top].di = d;
}
void GetTop(int &x, int &y, int &d)	//取栈顶方块
{
x = data[top].i; y = data[top].j; d = data[top].di;
}
void Pop()						//退栈一个方块
{
top--;
}
void Setdi(int d)				//修改栈顶元素的di值
{
data[top].di = d;
}
void DispBox()					//输出栈中所有方块构成一条迷宫路径
{
int k;
cout << "一条迷宫路径如下:\n";
for (k = 0; k <= top; k++)
{
cout << "  (" << data[k].i << "," << data[k].j << ")";
if ((k + 1) % 5 == 0) cout << endl;	//每行输出5个方块
}
cout << endl;
}
};
class Maze1											//用栈求解一条迷宫路径类
{
int a[MaxSize][MaxSize];						//迷宫数组
int m, n;										//迷宫行列数
public:
void Seta(int mg[][MaxSize], int m1, int n1)	//设置迷宫数组
{
int i, j;
m = m1; n = n1;
for (i = 0; i<m; i++)
for (j = 0; j<n; j++)
a[i][j] = mg[i][j];
}
bool mgpath(int xi, int yi, int xe, int ye)		//求一条从(xi,yi)到(xe,ye)的迷宫路径
{
int i, j, di, i1, j1;
bool find;
Stack st;									//建立一个空栈
st.Push(xi, yi, -1);						//入口方块进栈
a[xi][yi] = -1;								//为避免来回找相邻方块,将进栈的方块置为-1
while (!st.StackEmpty())					//栈不空时循环
{
st.GetTop(i, j, di);					//取栈顶方块,称为当前方块
if (i == xe && j == ye)					//找到了出口,输出栈中所有方块构成一条路径
{
st.DispBox();
return true;						//找到一条路径后返回true
}
find = false;							//否则继续找路径
while (di<4 && !find)					//找下一个相邻可走方块
{
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 (a[i1][j1] == 0) find = true;	//找到下一个可走相邻方块(i1,j1)
}
if (find)								//找到了下一个可走方块
{
st.Setdi(di);						//修改原栈顶元素的di值
st.Push(i1, j1, -1);				//下一个可走方块进栈
a[i1][j1] = -1;						//为避免来回找相邻方块,将进栈的方块置为-1
}
else									//没有路径可走,则退栈
{
a[i][j] = 0;						//恢复当前方块的迷宫值
st.Pop();							//将栈顶方块退栈
}
}
return false;								//没有找到迷宫路径,返回false
}
};
void main()
{
int mg[][MaxSize] = { { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 1, 0, 0, 1, 0, 0, 0, 1, 0, 1 },
{ 1, 0, 0, 1, 0, 0, 0, 1, 0, 1 }, { 1, 0, 0, 0, 0, 1, 1, 0, 0, 1 },
{ 1, 0, 1, 1, 1, 0, 0, 0, 0, 1 }, { 1, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
{ 1, 0, 1, 0, 0, 0, 1, 0, 0, 1 }, { 1, 0, 1, 1, 1, 0, 1, 1, 0, 1 },
{ 1, 1, 0, 0, 0, 0, 0, 0, 0, 1 }, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } };
Maze1 mz;									//创建一个Maze1对象mz
mz.Seta(mg, 10, 10);						//设置迷宫数组
cout << "求(1,1)到(8,8)的迷宫路径\n";
if (!mz.mgpath(1, 1, 8, 8))					//求入口为(1,1)出口为(8,8)的迷宫路径
cout << "不存在迷宫路径\n";
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: