• 迷宫求解


    栈的应用

    迷宫求解

    任务:可以输入一个任意大小的迷宫数据,用非递归的方法求出一条走出迷宫的路径,并将路径输出;

    源代码:

    #include<stdio.h>

    #include<stdlib.h>

    /*数据定义*/

    typedefenum { ERROR, OK } Status;

    typedefstruct

    {

             int row;            //row表示"行"号

             int line;           //line表示"列"号

    }PosType;                 //位置的元素类型

    typedefstruct

    {

    Int ord;        //该通道在路径上的"序号"        

    PosType seat;       //通道块在迷宫中的"坐标位置"

    int     di;         //从此通道走向下以通道块的"方向"

    }SElemType;             //栈的元素类型

    typedefstruct

    {

             SElemType * base;

             SElemType * top;

             intstacksize;

    }SqStack;

    /*函数原型说明*/

    Status InitStack(SqStack&S);                        //创建一个空栈S

    Status Push(SqStack&S,SElemType&a);                //插入新元素a

    Status Pop(SqStack&S,SElemType&a);                 //删除栈顶元素,a返回其值

    Status StackEmpty(SqStack S);                        //检查是否空栈

    Status MazePath(int maze[12][12],SqStack&S, PosType start, PosType end); //找通路

    void Initmaze(int maze[12][12],intx,int y);            //初始化迷宫

    void printmaze(int maze[12][12],intx,int y);           //显示迷宫

    Status Pass(int maze[12][12],PosTypeCurPos);        //判断当前位置是否可通

    void Markfoot(int maze[12][12], PosTypeCurPos);     //标记当前位置不可通

    PosTypeNextPos(PosTypeCurPos, intDir);            //进入下一位置

    void printpath(int maze[12][12],SqStackS,intx,inty,PosTypestart,PosType end); //显示通路

    /*主函数*/

    void main (void)

    {

             PosType start,end;

             int t=0;

             SqStack S;

             int maze[12][12];       

             do{

                       if(t!=0)

                       printf("\n");

                       for(int i=0;i<20;i++)

                       {

                                printf("* ");

                       }

    if(t==0)

                       {       

                                printf("\n*\t欢迎来到迷宫世界\t      * \n");

                                printf("*\t 1.设置迷宫\t\t      * \n");

                       }

                       else

                       {

                                printf("\n* 请继续选择:\t\t\t      * \n");

                                printf("*\t 1.设置迷宫\t\t      * \n");

                       }

                       printf("*\t 2.设置迷宫路径\t\t      * \n");

                       printf("*\t 3.输出迷宫通路路径\t      * \n");

                       printf("*\t 4.结束\t\t\t      *\n");

                       t++;

                       for(int j=0;j<20;j++)

                       {

                                printf("* ");

                       }

                       printf("\n");

                       int s;

                       printf("请选择:");

                       scanf("%d",&s);

                       intaa;         intx,y;

                       switch(s)

                       {

                       case 1://1.初始化迷宫

                                aa=1;

                                printf("迷宫设置:请输入\n"); //设置迷宫大小

                                do

                                {

                                         printf("行X(x<10)=");

                                         scanf("%d",&x);

                                         printf("列Y(y<10)=");

                                         scanf("%d",&y);

                                         if(x<1 || x>10||y<1 || y>10)

                                         {

                                                   printf("输入错误!\n");

                                         }

                                }while(x<1 || x>10||y<1 || y>10);                 

                                Initmaze(maze,x,y);           //初始化迷宫

                                printmaze(maze,x,y);          //显示所创建的迷宫

                                break;

                       case 2://寻找迷宫路径

                                if(aa==1)

                                {

                                         aa=2;                                      //设置入口和出口

                                         do{

                                                   printf("输入入口行坐标:");scanf("%d",&start.row);

                                                   if(start.row>x)

                                                            printf("输入错误!\n");

                                         }while(start.row>x);

                                         do{

                                                   printf("输入入口列坐标:");scanf("%d",&start.line);

                                                   if(start.line>y)

                                                            printf("输入错误!\n");

                                         }while(start.line>y);

                                         do{

                                                   printf("输入出口行坐标:");scanf("%d",&end.row);

                                                   if(end.row>x)

                                                            printf("输入错误!\n");

                                         }while(end.row>x);

                                         do{

                                                   printf("输入出口列坐标:");scanf("%d",&end.line);

                                                   if(end.line>y)

                                                            printf("输入错误!\n");

                                         }while(end.line>y);      

                                }

                                else

                                         printf("请先初始化迷宫!\n");   

                                printf("\n所设置入口坐标为(%d,%d),出口坐标为(%d,%d).\n",start.row,start.line,end.row,end.line);  

                                break;

                       case 3://输出此迷宫通路路径

                                if(aa==2)

                                {

                                         aa=3;

                                         if(MazePath(maze,S,start,end)) //若有通路,显示通路

                                                   printpath(maze,S,x,y,start,end);

                                         else

                                                   printf("\n抱歉,找不到通路!\n\n");

                                }

                                else

                                         printf("请先初始化迷宫并寻找路径!\n");

                                break;

             case 4:exit(0);

                                break;

                       default:

                                exit(0);

             }      

             }while(1);

    }

    /*若迷宫maze中从入口 start到出口 end的通道,则求得一条存放在栈中 */

    Status MazePath(int maze[12][12],SqStack&S, PosType start, PosType end)

    {

             PosType curpos;

             Int curstep;

             SElemType e;

             InitStack(S);

             curpos = start;                         // 设定"当前位置"为"入口位置

             curstep = 1;                            // 探索第一步

             do {

                       if (Pass(maze,curpos))              // 当前位置可通过,即是未曾走到过的通道块

                       {

                                Markfoot(maze,curpos);          // 留下足迹            

                                e.di =1;

                                e.ord = curstep;

                                e.seat= curpos;

                                Push(S,e);                           // 加入路径

                                if (curpos.row==end.row&&curpos.line==end.line)

                                         return OK;                  // 到达终点(出口)

                                curpos = NextPos(curpos, 1);   // 下一位置是当前位置的东邻

                                curstep++;                     // 探索下一步                           

                       }

        else                               // 当前位置不能通过

           {

                       if (!StackEmpty(S))

                       {

                   Pop(S,e);

    while (e.di==4 && !StackEmpty(S))

                                   {

    Markfoot(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 ERROR;

    }

    /*初始化迷宫时间复杂度:n^2*/

    voidInitmaze(int maze[12][12],intx,int y)

    {

    char select;

             do{

             printf("创建方式 A:自动生成 B:手动创建\n");

    label:          scanf("%c",&select);

                                if(select=='a'||select=='A') //自动生成

                         {                               

                                for(int i=1;i<x+1;i++)

                                  {

                                         for(int j=1;j<y+1;j++)

                                                   maze[i][j]=rand()%2;                              

                                  }                      

                                break;                          

                         }

                         else if(select=='b'||select=='B') //手动设置

                         {

                                printf("按行输入%d*%d数据,0代表可通,1代表不可通(每行以Enter结束):\n",x,y);

                                for(int i=1;i<x+1;i++)

                                  {

                                         for(int j=1;j<y+1;j++)

                                                   scanf("%d",&maze[i][j]);

                                         maze[i][y+1]=1;

                                  }

                                for(i=0;i<x+2;i++)maze[x+1][i]=1;

                                break;

                         }

                         else if(select=='\n')goto label;      //排除Enter键的影响

                       else

                                if(select!='b'||select!='B'||select!='a'||select!='A')

                                         printf("输入错误!\n");

             }while(select!='b'||select!='B'||select!='a'||select!='A');

    }

    /*显示迷宫时间复杂度:n^2*/

    voidprintmaze(int maze[12][12],intx,int y)

    {

             printf("\n\n");

             printf("显示所建的迷宫(#表示墙):\n");

             printf("%c ",'#');

             printf("%c ",'y');

             for(int j=1;j<y+1;j++)

                       printf("%d ",j);

    printf("%c ",'#');

             printf("\nx ");

    for(int i=1;i<y+3;i++)

                       printf("%c ",'#');

             printf("\n");                 

             for(i=1;i<x+1;i++)

             {

                       if(i<x+1)

                                printf("%d ",i);            

                       else

                                printf("%c ",'#');

                       printf("%c ",'#');

    for(int j=1;j<y+1;j++)

                       {

                                printf("%d ",maze[i][j]);

                       }

                       printf("%c",'#');

                       printf("\n");

             }

    for(i=0;i<y+3;i++)printf("%c ",'#');printf("\n");

    }

    /*输出路径时间复杂度:n^2*/

    voidprintpath(int maze[12][12],SqStackS,intx,inty,PosTypestart,PosType end)

    {

             printf("\n\n\001通路路径:\n");

             SElemType * p=S.base;

             while(p!=S.top)

             {

                       maze[p->seat.row][p->seat.line]=2;      //标记为路径中的点

    p++;

             }

             printf("\001路径图为:\n");

             printf("%c ",'#');

             printf("%c ",'y');

             for(int j=1;j<y+1;j++)

                       printf("%d ",j);

    printf("%c ",'#');

                       printf("\nx ");  

    for(int m=1;m<y+3;m++)

                       printf("%c ",'#');

             printf("\n");

             for(int i=1;i<x+1;i++)

             {

                                if(i<x+1)

                                printf("%d ",i);            

                       else

                                printf("%c ",'#');

                       printf("%c ",'#');

                       for(int j=1;j<y+1;j++)

                       {

                                if(maze[i][j]==2)

                                {if(i==start.row&&j==start.line||i==end.row&&j==end.line){

                                         if(i==start.row&&j==start.line)

                                                   printf("i ");

                                if(i==end.row&&j==end.line)

                                                   printf("o ");}

                                         else

                                         printf("%c ",' ');}

                                else

                                         printf("%c ",'#');

                       }

                       printf("%c ",'#');

                       printf("\n");

             }

                       for(i=0;i<y+3;i++)

                                         printf("%c ",'#');

                                printf("\n\n");

                       printf("\001路径线路为:\n");

                       SqStack M;

                       InitStack(M);

                       SElemType a;

                       while (!StackEmpty(S))

                       {      

                                Pop(S,a);

                                Push(M,a);

                       }

                       while (!StackEmpty(M))

                       {      

                                Pop(M,a);

                                printf("(%d,%d)",a.seat.row,a.seat.line);

                       }

                       printf("\n");       

                       printf("路径输出成功!\n");

    }

    /* 判断当前位置是否可通*/

    Status Pass(int maze[12][12],PosTypeCurPos)

    {

             if(maze[CurPos.row][CurPos.line]==0)

                       return OK;                              // 如果当前位置是可以通过,返回1

    else

                       return ERROR;                        // 其它情况返回0

    }

    /* 标记当前位置不可通*/

    voidMarkfoot(int maze[12][12],PosTypeCurPos)

    {

             maze[CurPos.row][CurPos.line]=1;

    }

    /*进入下一位置*/

    PosTypeNextPos(PosTypeCurPos, intDir)

    {

             PosType ReturnPos;

             switch (Dir)

             {

    case 1:

    ReturnPos.row=CurPos.row;

    ReturnPos.line=CurPos.line+1;

    break;

    case 2:

    ReturnPos.row=CurPos.row+1;

    ReturnPos.line=CurPos.line;

    break;

    case 3:

    ReturnPos.row=CurPos.row;

    ReturnPos.line=CurPos.line-1;

    break;

    case 4:

    ReturnPos.row=CurPos.row-1;

    ReturnPos.line=CurPos.line;

    break;

             }

             returnReturnPos;

    }

    /*创建一个空栈S*/

    Status InitStack(SqStack&S)

    {

             S.base=(SElemType *)malloc(100*sizeof(SElemType));

             if(!S.base)return ERROR;

             S.top=S.base;

             S.stacksize=100;

             return OK;

    }

    /*插入新元素a*/

    Status Push(SqStack&S,SElemType&a)

    {

        *S.top++=a;

             return OK;

    }

    /* 删除栈顶元素,a返回其值*/

    Status Pop(SqStack&S,SElemType&a)

    {

             if(S.top==S.base)return ERROR;

             a=*--S.top;

             return OK;

    }

    /*检查是否空栈*/

    Status StackEmpty(SqStack S)

    {

             if(S.top==S.base)return OK;

             return ERROR;

    }

  • 相关阅读:
    ftp>ls 未连接
    Error running 'run': data.userName must not be null
    Excel另存为_有些Excel打开时会出现一些提示
    23种设计模式通俗理解
    清除html中的标记,只留下文字
    将DataTable中的数据导出成Excel
    C#读取文件
    系统性能瓶颈分析
    Angularjs的My97DatePicker扩展
    Memcache修改端口
  • 原文地址:https://www.cnblogs.com/xiohao/p/3034716.html
Copyright © 2020-2023  润新知