#include<iostream>
#include<fstream>
using namespace std;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
#define INIT_SIZE 100 //存储空间初始分配量
#define INCREMENT 10 //存储空间分配增量
//迷宫元素的位置
typedef struct{
int r;//迷宫中r行的位置
int c;//迷宫中c列的位置
}PostType;
//栈元素类型结构
typedef struct{
int ord; //当前位置在路径上的序号
PostType seat;//当前坐标
int di; //往下一坐标的方向
}SElemType;
//栈结构
typedef struct{
SElemType* base;//栈基址,构造前销毁后为空
SElemType* top;//栈顶
int stackSize; //栈容量
}SqStack;
//构造空栈s
Status InitStack(SqStack &S){
S.base=(SElemType*)malloc(INIT_SIZE *sizeof(SElemType));
if(!S.base)
exit(OVERFLOW);//存储分配失败
S.top=S.base;
S.stackSize=INIT_SIZE;
return OK;
}
//判断栈是否为空
Status StackEmpty(SqStack S){
//若s为空,则返回TRUE,否则返回FALSE
if(S.top==S.base)
return TRUE;
else
return FALSE;
}
//进栈
Status Push(SqStack &S,SElemType e){//插入元素e为新的栈顶元素
if(S.top-S.base >=S.stackSize){//栈满,加空间
S.base=(SElemType *)realloc(S.base,(S.stackSize+INCREMENT)*sizeof(SElemType));
if(!S.base)
exit(OVERFLOW); //存储分配失败
S.top=S.base+S.stackSize;
S.stackSize+=INCREMENT;
}
*S.top++=e;
return OK;
}
//出栈
Status Pop(SqStack &S,SElemType &e){
//若栈不空删除栈,则顶元素用e返回并返回OK,否则返回ERROR
if(S.top==S.base)
return ERROR;
e=*--S.top;
return OK;
}
#define MAXLENGTH 100//迷宫包括外墙最大行列数目
//迷宫类型
typedef struct{
int m[MAXLENGTH][MAXLENGTH];
}MazeType;
//判断位置是否可通
Status Pass(MazeType maze,PostType curpos){
//当前位置可通则返回TURE,否则返回FALSE
if(maze.m[curpos.r][curpos.c]==1||maze.m[curpos.r][curpos.c]==2||maze.m[curpos.r][curpos.c]==3)// "1、2、3"表示可通
return TRUE;
else
return FALSE;
}
//留下可通的足迹
Status FootPrint(MazeType &maze,PostType curpos){//走过并且可通返回OK
maze.m[curpos.r][curpos.c]=4;//"4"表示可通
return OK;
}
//搜索位置
PostType NextPos(PostType &curpos,int di){//指示并返回下一位置的坐标
PostType cpos;
cpos=curpos;
switch(di){
//1.2.3.4分别表示东,南,西,北方向
case 1:cpos.c+=1; break;
case 2:cpos.r+=1; break;
case 3:cpos.c-=1; break;
case 4:cpos.r-=1; break;
default: exit(ERROR);
}
return cpos;
}
//留下走过但不可通的足迹
Status MarkPrint(MazeType &maze,PostType curpos){//曾走过但不是通路标记并返回OK
maze.m[curpos.r][curpos.c]=5;//"5"表示曾走过但不通
return OK;
}
//寻找迷宫路径
Status MazePath(SqStack &S,MazeType &maze,PostType start,PostType end){
//若迷宫maze存在,从入口start到end的通道求得一条路径,且存放在栈中,并返回TRUE,否则返回FALSE
PostType curpos;
int curstep;//当前序号,1.2.3.4分别表示东,南,西,北方向
SElemType e;
InitStack(S);
curpos=start; //设置"当前位置"为"入口位置"
curstep=1; //探索第一步
do{
if(Pass(maze,curpos)){//当前位置可以通过,即是未曾走到过的通道
FootPrint(maze,curpos);//留下足迹
e.ord=curstep;
e.seat=curpos;
e.di=1;
Push(S,e); //加入路径
if(curpos.r==end.r&& curpos.c==end.c)
return TRUE; //到达终点(出口)
else{
curpos=NextPos(curpos,1); //下一位置是当前位置的东邻
curstep++; //探索下一步
}
}
else{
if(!StackEmpty(S)){
Pop(S,e);
while(e.di==4&& !StackEmpty(S)){
MarkPrint(maze,e.seat);
Pop(S,e);//留下不能通过的标记,并退一步
}
if(e.di<4){
e.di++;//换下一个方向探索
Push(S,e);
curpos=NextPos(e.seat,e.di);//设定当前位置是该新方向上的相邻
}
}
}
}while(!StackEmpty(S));
return FALSE;
}
//输出迷宫图形
Status PrintMaze(MazeType &maze,int x,int y){
for(int i=0;i<x;i++){
for(int j=0;j<y;j++)
cout<<maze.m[i][j]<<" ";
cout<<endl;
}
return OK;
}
//输出迷宫路径坐标
Status PrintPath(SqStack &S){
while(S.base != S.top){
cout<<"("<<S.base->seat.r<<","<<S.base->seat.c<<") ";
S.base++;
if(S.base!=S.top)
cout<<"-> ";
}
return OK;
}
//从文本中输入迷宫图
Status Load_Sq(SqStack &S,MazeType &maze,char *filename,int &m,int &n)
{
ifstream infile;
infile.open(filename,ios::in);
if(!infile)
{
cerr<<filename<<" can't open!"<<endl;
abort();
}
infile>>m>>n;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
infile>>maze.m[i][j];
cout<<maze.m[i][j]<<" ";
}
cout<<endl;
}
infile.close();
return OK;
}
//把迷宫地图保存到文本中
Status Save_Sq(SqStack &S,MazeType &maze,char *filename,int m,int n)
{
ofstream outfile(filename,ios::out);
if(!outfile)
{
cerr<<filename<<" can't open!"<<endl;
abort();
}
outfile<<m<<" "<<n<<endl;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++)
outfile<<maze.m[i][j]<<" ";
outfile<<endl;
}
outfile.close();
return OK;
}
//主函数
void main()
{
cout<<"------------------欢迎来到迷宫世界----------------------"<<endl<<endl;
cout<<"-------0表示围墙,1表示通道,2表示起点,3表示终点-------"<<endl;
cout<<"----------4表示路径,5表示走过但不可通的通道------------"<<endl<<endl;
SqStack SqPoint,S;
MazeType maze;
PostType start,end;
int m,n,d;
char ch,filename[32];
do{
cout<<endl<<"---------------请输入选择1、2、3------------------"<<endl;
cout<<"--1表示使用文本迷宫,2表示重创迷宫,3表示退出程序--选择:";
cin>>d;
cout<<endl;
switch(d){
case 1:{
cout<<"请输入要打开的迷宫地图文件名,如: maze.txt :";
cin>>filename;
cout<<"迷宫的结构图如下:"<<endl;
Load_Sq(S,maze,filename,m,n);
for(int j=0;j<m;j++){
for(int k=0;k<n;k++){
if(maze.m[j][k]==2){
start.r=j;
start.c=k;
}
if(maze.m[j][k]==3){
end.r=j;
end.c=k;
}
}
}
if(MazePath(SqPoint,maze,start,end)){
cout<<endl<<"此迷宫从入口到出口的一条路径,如下图所示:"<<endl;
maze.m[start.r][start.c]=2;
maze.m[end.r][end.c]=3;
PrintMaze(maze,m,n);
cout<<endl<<"此迷宫从入口到出口的路径坐标,如下所示:"<<endl;
PrintPath(SqPoint);
cout<<endl;
}
else
cout<<"此迷宫没有从入口到出口的路径!"<<endl;
}break;
case 2:
{
int i,j;
cout<<"请输入迷宫的行数m (0<m<=100)和列数n (0<n<=100):";
cin>>m>>n;
cout<<"-------0表示围墙,1表示通道,2表示起点,3表示终点-------"<<endl;
cout<<endl<<"------------------请输入迷宫地图------------------"<<endl;
for(i=0;i<m;i++){
for(j=0;j<n;j++){
cin>>maze.m[i][j];
if(maze.m[i][j]==2){
start.r=i;
start.c=j;
}
if(maze.m[i][j]==3){
end.r=i;
end.c=j;
}
}
}
cout<<endl<<"请输入Y(y) or N(n),Y(y)保存迷宫地图,N(n)不保存迷宫地图:";
cin>>ch;
if(ch=='Y'||ch=='y'){
cout<<"请输入要保存的迷宫地图文件名,如: maze.txt :";
cin>>filename;
Save_Sq(S,maze,filename,m,n);
cout<<"迷宫地图保存成功!"<<endl;
}
if(ch=='N'||ch=='n'){
cout<<"未保存迷宫地图!"<<endl;
}
if(MazePath(SqPoint,maze,start,end)){
cout<<endl<<"此迷宫从入口到出口的一条路径,如下图所示:"<<endl;
maze.m[start.r][start.c]=2;
maze.m[end.r][end.c]=3;
PrintMaze(maze,m,n);
cout<<endl<<"此迷宫从入口到出口的路径坐标,如下所示:"<<endl;
PrintPath(SqPoint);
cout<<endl;
}
else
cout<<"此迷宫没有从入口到出口的路径!"<<endl;
}break;
default:break;
}
}while(d>0&&d<3);
cout<<endl<<"------------感谢您光临迷宫世界,再会!------------------"<<endl<<endl;
}
http://blog.sina.com.cn/s/blog_990ee2ba0100wq51.html转自