栈实现迷宫求解

实现的伪代码
设定当前位置的初始值为入口位置
do{
若当前位置可通
则 {
若当前位置插入栈顶; //纳入路径
若该位置是出口位置,则结束; //求得路径存放在栈中
否则切换当初位置的东邻方块为新的当前位置;
}
否则,
若栈不空且栈顶位置尚有其他方向未经探索,
则设定新的当前位置为沿顺时针找到的栈顶位置的下一相邻块;
若栈不空但栈顶位置与四周均不可同,
则 { 删去栈顶位置,
若栈不空,则重新测试新的栈顶位置,
直至找到一个可通的相邻块或出栈至栈空;
}
}while(栈不空);

代码实现
关于栈的stack.h

//=======Stack 的表示与实现
//=====栈的顺序存贮结构
#define STACK_INIT_SIZE 100  // 存储空间的初始分配量
#define STACKINCREMENT 10    //存储空间分配增量
//-------------栈的顺序存储表示----------------
typedef struct
{
    SElemType *base;  //栈底指针
    SElemType *top;   //栈顶指针
    int stacksize;    //当前可使用的最大容量
} SqStack;
//------------基本操作--------------------
//构建一个空栈S
Status InitStack(SqStack &S)
{
    S.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
    if(!S.base)  //判断是否空间分配成功
        exit(OVERFLOW);
    S.top = S.base; //栈顶与栈底指向同一个位置,表示空栈
    S.stacksize = STACK_INIT_SIZE;
    return OK;
}//InitStack_Sq
//销毁栈S
Status DestroyStack(SqStack &S)
{
    if(S.base)
    {
        free(S.base);
        S.stacksize = 0;
        return OK;
    }
    else
        return ERROR;
}//DestroyStack_Sq
//初始条件:栈S存在
//操作结果:清空栈
Status CleanStack(SqStack &S)
{
    S.top = S.base;
    return OK;
}//CleanStack_Sq
//初始条件:栈S存在
//操作结果:若为空栈,返回TRUE,否则FALSE
Status StackEmpty(SqStack S)
{
    if(S.top == S.base)
        return TRUE;
    else
        return FALSE;
}//StackEmpty_Sq
//初始条件:栈S存在
//操作结果:返回栈内元素个数,即栈的长度
int StackLength(SqStack S)
{
    int len;
    len = (S.top - S.base);
    return len;
}//StackLength_Sq
//初始条件:栈S存在
//操作结果:用e返回S的栈顶元素
Status GetTop(SqStack S, SElemType &e)
{
    if(S.top == S.base)//判空
        return ERROR;
    else
    {
        e = *(S.top - 1);
        return OK;
    }
}//GetTop_Sq
//初始条件:栈S存在
//操作结果:插入元素e为新的栈顶元素
Status Push(SqStack &S, SElemType e)
{
    //判满,追加存储空间
    if(S.top - S.base >= S.stacksize)
    {
        S.base = (SElemType *)realloc(S.base,(S.stacksize + STACKINCREMENT) * sizeof(SElemType));
        if(!S.base)//存储分配失败
            exit(OVERFLOW);
        S.top = S.base + S.stacksize;
        S.stacksize += STACKINCREMENT;
    }
    *S.top++ = e; //插入元素
    return OK;
}//Push_Sq
//初始条件:栈S存在
//操作结果:删除S的栈顶元素,并用e返回其值
Status Pop(SqStack &S, SElemType &e)
{
    if(S.top == S.base) //判空
        return ERROR;
    e = *--S.top; //返回删除元素的值
    return OK;
}//Pop_Sq
//初始条件:栈S存在
//操作结果:遍历栈元素并显示
Status StackTraverse(SqStack S)
{
    if(S.base)   //判断栈是否存在
    {
        if(S.top == S.base); //判空
        else
        {
            SElemType *p;
            p = S.base;
            while(p <S.top)
            {
                Print_Selem(*p);
                p++;
            }
            printf("\b\b  ");
            printf("\n");
        }
        return OK;
    }
    else
    {
        return ERROR;
    }
}//StackTraverse_Sq

关于迷宫的maze.h

//判断当前位置是否可以通过(是否有墙)
void IntMaze(MazeType &maze)
{
    int i,j;
    char a[10][10] =
    {
        {'#','#','#','#','#','#','#','#','#','#'},
        {'#',' ',' ','#',' ',' ',' ','#',' ','#'},
        {'#',' ',' ','#',' ','#','#','#',' ','#'},
        {'#',' ',' ',' ',' ','#','#','#',' ','#'},
        {'#',' ','#','#','#','#','#','#',' ','#'},
        {'#',' ',' ',' ','#','#','#','#',' ','#'},
        {'#',' ','#',' ',' ',' ','#','#',' ','#'},
        {'#',' ','#','#','#',' ','#','#',' ','#'},
        {'#','#',' ',' ',' ',' ',' ',' ',' ','#'},
        {'#','#','#','#','#','#','#','#','#','#'}
    };
    maze=new char *[10];
    for(i=0; i<10; i++)
        maze[i]=new char[10];
    for(i=0; i<10; i++)
        for(j=0; j<10; j++)
            maze[i][j]=a[i][j];
}
void CreatMaze(MazeType &maze,int m,int n)
{
    int i;
    maze=new char *[m];
    for(i=0; i<m; i++)
        maze[i]=new char[n];
}
void print_maze(MazeType maze,int m=10,int n=10)
{
    int i,j;
    printf(" ");
    for(i=0;i<n;i++) printf("%d",i);
    printf("\n");
    for(i=0; i<m; i++)
    {
        printf("%d",i);
        for(j=0; j<n; j++)
            printf("%c",maze[i][j]);
        printf("\n");
    }
}
Status Pass(PosType curpos,MazeType maze)
{
    if(maze[curpos.x][curpos.y]==' ') return OK;
    else return ERROR;
}
void FootPrint(PosType curpos,MazeType &maze)
{
    maze[curpos.x][curpos.y]='@';
}
PosType NextPos(PosType curpos,int di)
{
    if(di==1) curpos.y++;
    else if(di==2) curpos.x++;
    else if(di==3) curpos.y--;
    else if(di==4) curpos.x--;
    return curpos;
}
void MarkPrint(PosType curpos,MazeType &maze)
{
    maze[curpos.x][curpos.y]=',';
}
Status MazePath(MazeType &maze,PosType start,PosType end)
{
    SqStack S;
    SElemType e;
    InitStack(S);
    PosType curpos = start;  //设定"当前位置" 为 "入口位置"
    int curstep = 1;             //探索第一步
    do
    {
        if(Pass(curpos,maze))    //当前位置可以通过,即是未曾走到过的通道块
        {
            FootPrint(curpos,maze);     //留下足迹
            e = {curstep,curpos,1};
            Push(S,e);                //加入路径
            if(curpos == end )
            {
                printf("迷宫有通路,通路为:\n");
                StackTraverse(S);
                return(TRUE);  //到达出口
            }
            curpos = NextPos(curpos,1);   //下一位置是当前位置的东邻
            curstep++;             //探索下一步
        }
        else
        {
            if(!StackEmpty(S))
            {
                Pop(S,e);
                while(e.di==4 && !StackEmpty(S))
                {
                    MarkPrint(e.seat,maze);          //留下不能通过的标记,
                    Pop(S,e);                //退回一步
                }
            }
            if(e.di<4)
            {
                e.di++;
                Push(S,e);                  //换下一个方向探索
                curpos = NextPos(e.seat,e.di);       //设定当前位置是该方向上的相邻块
            }
        }
    }
    while(!StackEmpty(S));
    printf("迷宫没有通路");
    return FALSE;
}

Base.h

#include<stdio.h>
#include <stdlib.h>  //malloc
//函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
//Status是函数的类型,其值是函数结果状态代码
typedef int Status;
typedef char** MazeType;
//----坐标的数据元素------
typedef struct PosType
{
    int x;
    int y;
    bool operator==(const PosType p)const
    {
        return(this->x == p.x&&this->y == p.y);
    }
} PosType;
//输出点坐标
void Print_Pos(PosType Pos)
{
    printf("(%d,%d)",Pos.x,Pos.y);
}
//------迷宫中栈的元素类型
typedef struct
{
    int ord; //通道块在路径上的"序号"
    PosType seat; //通道块在迷宫中的“坐标位置”
    int di; //在此通道块走向下一通道块的“方向”
} SElemType;
//输出SlemType
void Print_Selem(SElemType s)
{
    printf("(%d,%d)->",s.seat.x,s.seat.y);
}
//----迷宫的元素类型

Print.h

void start_print()
{
    printf("***********************************************************************************************************************\n");
    printf("                  数据结构实验二                         \n");
    printf("          迷宫求解----深度优先搜索(栈实现)                  \n");
    printf("                 中国海洋大学                            \n");
    printf("***********************************************************************************************************************\n");
}
void Creathelp_print(int & m,int & n,MazeType &maze,PosType &start,PosType &end)
{
    int i,j;
    printf("**请输入迷宫的长和宽*\n");
    scanf("%d %d",&m,&n);
    getchar();
    char a[m][n];
    printf("**请输入迷宫(#为墙,空白符为路):**\n");
    for(i=0; i<m; i++)
    {
        for(j=0;j<n;j++)
            scanf("%c",&a[i][j]);
        getchar();
    }
    CreatMaze(maze,m,n);
    for(i=0;i<m;i++)
        for(j=0;j<n;j++)
             maze[i][j]=a[i][j];
    printf("起点(x,y)=(");
    scanf("%d,%d)",&start.x,&start.y);
    printf("终点(x,y)=(");
    scanf("%d,%d)",&end.x,&end.y);
}
void menu1_print()
{
    printf("***********************************************************************************************************************\n");
    printf("        请选择  1.默认迷宫  2.新建迷宫  0.退出               \n");
    printf("***********************************************************************************************************************\n");
}
void menu2_print()
{
    printf("***********************************************************************************************************************\n");
    printf("        请选择  1.打印 A+B   2.打印 AXB    3.对多项式进行操作    0.退出                \n");
    printf("***********************************************************************************************************************\n");
}
void output_tip_print(char a)
{
    printf("多项式%c: ",a);
}
void over_print()
{
    system("CLS");
    printf("      *******  *               *           \n");
    printf("         *     *               *           \n");
    printf("         *     ***  ***   ***  * *   **    \n");
    printf("         *     * *  * *   * *  **    *     \n");
    printf("         *     * *  ****  * *  * *  **     \n");
}``

main.cpp

#include"Base.h"
#include"stack.h"
#include"maze.h"
#include"Print.h"
int main()
{
    system("color F4"); //改变背景色和前景色
    start_print();
    system("pause");  //冻结屏幕
    system("CLS");   //清屏操作
    MazeType maze;
    PosType start,end;
    int a;// a进行输入控制
    do
    {
        system("CLS");
        do
        {
            menu1_print();
            scanf("%d",&a);
            if(a==1)
            {
                IntMaze(maze);
                printf("迷宫如下:(#代表墙 空白代表路)\n");
                print_maze(maze);
                start= {1,1};
                end= {8,8};
                printf("按任意键求解");
                system("pause");
                MazePath(maze,start,end);
                printf("图如下:\n");
                print_maze(maze);
                printf("(@代表通路 ,代表算法中探索过得路径)\n");
            }
            else if(a==2)
            {
                int m,n;
                Creathelp_print(m,n,maze,start,end);
                print_maze(maze,m,n);
                printf("按任意键求解");
                system("pause");
                MazePath(maze,start,end);
                printf("图如下:\n");
                print_maze(maze,m,n);
                printf("(@代表通路 ,代表算法中探索过得路径)\n");
            }
            else if(a==0)
            {
                over_print();
                return 0;
            }
        }
        while(1);
    }while(a!=0);
}

效果展示

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值