#include<iostream>
using namespace std;
struct ElemType //栈中元素(记录类型)
{
int i,j,v; //i、j是位置的行列坐标,v是试探的方向
}stk;
struct SeqStack //顺序栈的结构类型定义
{
ElemType *stack;
int top;
int MaxSize;
};
//**************//
//*初始化顺序栈*//
//**************//
void InitStack(SeqStack &S,int ms)
{
if(ms<=0) //检查ms值
{
cout<<"Invalid ms!"<<endl;exit(1);
}
S.stack=new ElemType[ms]; //为顺序栈动态分配存储空间
if(!S.stack){
cerr<<"Memory allocation failure!"<<endl;
exit(1);
}
S.top=0; //置栈空
}
//**************//
//*数据元素入栈*//
//**************//
void Push(SeqStack &S,ElemType item)
{
if(S.top==300-1) //检查栈中是否还有空间
{cerr<<"Stackover flowed"<<endl;exit(1);}
S.top++; //移动栈顶指针,使其指向新的栈顶位置
S.stack[S.top].i=item.i; //新元素入栈
S.stack[S.top].j=item.j;
S.stack[S.top].v=item.v;
}
//**************//
//*数据元素退栈*//
//**************//
ElemType Pop(SeqStack &S)
{
if(S.top==0) //检查栈是否为空
{cerr<<"Stack is empty!"<<endl;
exit(1);
}
S.top--; //栈顶指针退1,使其指向新的栈顶位置
return S.stack[S.top+1]; //返回栈顶元素值
}
//****************//
//*判断栈是否为空*//
//****************//
bool empty(SeqStack &S)
{ if(S.top==0)return 1;
else return 0;
}
//*********************************//
//*替换找到路径的迷宫,通路用3代替*//
//*********************************//
void out(SeqStack &S,SeqStack &S1,int temp[][17]) //S1的作用是为了方便按照走通的顺序输出路径上每一步的位置坐标和下一步的方向
{
if(S.top==0)
{cerr<<"Stack is empty!"<<endl;
exit(1);
}
temp[S.stack[S.top].i][S.stack[S.top].j]=3; //将通路上的0用3进行替换
Push(S1,S.stack[S.top]); //利用栈的“先进后出”原理,将从原栈S中退出的元素压入新栈S1
S.top--;
}
//****************************//
//*输出走过的路径的坐标和方向*//
//****************************//
void outpath(SeqStack &S)
{
if(S.top==0)
{
cout<<"Stack is empty!"<<endl;
exit(1);
}
cout<<"("<<S.stack[S.top].i<<","<<S.stack[S.top].j<<","<<S.stack[S.top].v<<"),";
S.top--;
}
//************************//
//*输出找到通路的迷宫数组*//
//************************//
void Outputmaze(int maze[][17])
{
int m=12,n=15;
for(int x=0;x<m+2;x++)
{
for(int y=0;y<n+2;y++)
cout<<maze[x][y]<<" ";
cout<<endl;
}
}
int Maze_path(SeqStack &S,SeqStack &S1,int maze[][17],int mark[][17],int m,int n)
//maze迷宫数组,mark标记走过位置数组,m,n迷宫的行列数,迷宫走通返回1,否则返回0
{//定义并初始化方向增量数组
int move[8][2]={{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};
int g,h; //试探位置
mark[1][1]=1; //开始位置已经走过
stk.i=1;stk.j=1;stk.v=0; //当前位置(未入栈),且从正东方向开始试探
InitStack(S,300); //初始化栈S
InitStack(S1,250); //初始化栈S1
while(!empty(S)||stk.v<7) //只要迷宫中还有可试探的位置就一直试探
{
g=stk.i+move[stk.v][0];h=stk.j+move[stk.v][1]; //试探位置的坐标
if(g==m&&h==n&&maze[m][n]==0) //说明试探位置已到达迷宫出口,且迷宫口是通的
{Push(S,stk); //将当前位置入栈
stk.i=g;stk.j=h;stk.v=0; //将试探位置设为当前位置
Push(S,stk); //将试探位置入栈
while(!empty(S))out(S,S1,maze); //对求解出来的迷宫进行标记
cout<<"迷宫通路(用3代替路径):"<<endl;
Outputmaze(maze); //输出标记后的迷宫
cout<<"顺序输出走迷宫的位置坐标和下一步前进的方向:"<<endl;
while(!empty(S1))outpath(S1); //输出走通的顺序路径坐标
return 1;
}
else if(g==m&&h==n&&maze[m][n]!=0){ //走到了迷宫口,但没有出口
cout<<"no path1"<<endl;return 0;
}
else if(maze[g][h]==0&&mark[g][h]==0) //如果试探位置可通且是没有走过的地方
{mark[g][h]=1; //相当于走了一步
Push(S,stk); //将当前位置入栈
stk.i=g;stk.j=h;stk.v=0; //记下试探位置
}
else if(maze[g][h]==1||mark[g][h]==1) //否则,如果试探位置已经走过
{
if(stk.v<7)stk.v=stk.v+1; //如果当前方位小于7,就试探下一个方向
else
{
if(!empty(S))stk=Pop(S);
}
}
}
cout<<"No path"<<endl;
return 0;
}
void main()
{
void Push();
ElemType Pop();
bool empty();
void Outputmaze();
int maze[14][17]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,0,1,0,0,0,1,1,0,0,0,1,1,1,1,1,1,
1,1,0,0,0,1,1,0,1,1,1,0,0,1,1,1,1,
1,0,1,1,0,0,0,0,1,1,1,1,0,0,1,1,1,
1,1,1,0,1,1,1,1,0,1,1,0,1,1,0,0,1,
1,1,1,0,1,1,1,1,0,1,1,0,1,1,0,0,1,
1,1,1,0,1,0,0,1,0,1,1,1,1,1,1,1,1,
1,0,0,1,1,0,1,1,1,0,1,0,0,1,1,1,1,
1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,
1,0,0,1,1,0,1,1,0,1,1,1,1,1,0,1,1,
1,1,1,0,0,0,1,1,0,1,1,0,0,0,0,0,1,
1,0,0,1,1,1,1,1,0,0,0,1,1,1,1,0,1,
1,0,1,0,0,1,1,1,1,1,0,1,1,1,1,0,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
int mark[14][17]={0};
cout<<"原迷宫:"<<endl;
for(int i=0;i<14;i++){
for(int j=0;j<17;j++)cout<<maze[i][j]<<" ";cout<<endl;}
struct SeqStack M1,M2;
Maze_path(M1,M2,maze,mark,12,15);
cout<<endl;
}