用栈实现迷宫问题的求解,主要算法如下:
1、初始化;
2、以栈是否为空表示是否还有可能的路径,并作为循环终止条件;
3、在循环内分情况处理:
(1)若探测到下一个位置可行进,则将当前位置及将要移动的方向信息压栈,再移动到新位置;(要注意等上一个位置的全部信息都确定了后再压栈,不能忽略方向)
(2)若下一个位置不可行进,再分两种情况:
[1]若还有其它可能行进的方向,则通过一个while循环找到下一个可行进的方向;(要注意方向的初始值可能为最大值,要在while循环中检测方向的值是否溢出)
[2]若无其它可行方向,则返回上一个位置(即出栈),并将方向值加1表示新的试探方向;
4、若在循环内返回1则表明成功到达终点,反之若返回0则是由于所有可能的路径都走遍了导致栈空。
#include <iostream>
using namespace std;
const int MAXSIZE(100);
const int m(3);//行
const int n(4);//列
int maz[m + 2][n + 2]=
{
{ 1, 1, 1, 1, 1, 1 },
{ 1, 0, 0, 0, 0, 1 },
{ 1, 1, 0, 1, 1, 1 },
{ 1, 1, 0, 0, 0, 1 },
{ 1, 1, 1, 1, 1, 1 }
};
typedef struct { int x, y; } item;
typedef struct{ int x, y, d; } Datatype;
typedef struct{ int top; Datatype data[MAXSIZE]; }Seqstack,*pSeqstack;
pSeqstack init(void)
{
pSeqstack s;
s = (pSeqstack)malloc(sizeof(Seqstack));
if (s)
s->top = -1;
return(s);
}
int empty(pSeqstack s)
{
if (s->top == -1)
return(1);
else
return(0);
}
int push(pSeqstack s,Datatype x)
{
if (s->top == MAXSIZE - 1)
return(0);
else
{
++s->top;
s->data[s->top] = x;
return(1);
}
}
int pop(pSeqstack s, Datatype *x)
{
if (empty(s))
return(0);
else
{
*x = s->data[s->top];
--s->top;
return(1);
}
}
int get_top(pSeqstack s, Datatype *x)
{
if (empty(s))
return(0);
else
{
*x = s->data[s->top];
return(1);
}
}
void display()
{
cout << endl;
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 6; j++)
{
cout << maz[i][j] << "\t";
}
cout << endl;
}
}
int maize_out(int maize[][n+2])
{
item move[4] = { { 0, 1 }, { 0, -1 }, { 1, 0 }, { -1, 0 } };
/*初始化*/
int cur_x = 1, cur_y = 1, cur_dir = 0;
Datatype dat;
pSeqstack m_path = init();
maize[cur_x][cur_y] = -1;
/*当栈不为空时表明还有未试探的路径*/
do
{
if (cur_dir < 4 && maize[cur_x + move[cur_dir].x][cur_y + move[cur_dir].y] == 0)//当前指向位置可行
{
/*对新位置进行标记*/
maize[cur_x + move[cur_dir].x][cur_y + move[cur_dir].y] = -1;
/*此时上一个位置包含的信息(坐标及指向)已完全确定,压栈*/
dat.x = cur_x;
dat.y = cur_y;
dat.d = cur_dir;
push(m_path, dat);
/*将当前指向移到新位置*/
cur_x += move[cur_dir].x;
cur_y += move[cur_dir].y;
cur_dir = 0;
/*判断新位置是否为终点,不考虑迷宫出口与入口重合这种极端情况*/
if (cur_x == m&&cur_y == n)
{
maize[cur_x][cur_y] = -1;
return(1);
}
}
else //当前指向位置不可行
{
if (cur_dir < 4)//当前指向位置不可行,但还有其它可能行进方向
{
while (maize[cur_x + move[cur_dir].x][cur_y + move[cur_dir].y] != 0)
{
++cur_dir;
if (cur_dir >= 4)
break;
}
}
else//当前指向位置不可行,也没有其它可行进方向
{
pop(m_path, &dat);
cur_x = dat.x;
cur_y = dat.y;
cur_dir = dat.d + 1;
}
}
} while (!empty(m_path));
return(0);
}
int main()
{
int t= maize_out(maz);
display();
while (1)
{
}
return(1);
}