栈实现迷宫的较完善 程序

本文介绍了一种利用栈结构和迷宫路径搜索算法解决迷宫问题的方法,包括迷宫构造、路径搜索、路径输出及迷宫输入输出功能。通过文本输入或手动创建迷宫,实现从起点到终点的路径查找,并展示路径坐标和图形输出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#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转自
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值