C语言使用堆栈算法实现迷宫求解,VS2019调试

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>

#define  RIGHT 1
#define  ERROR 0
#define sizea 4
#define sizeb 4
#define STACK_INIT_SIZE 16
#define STACKINCREMENT 10
typedef struct
{
    int x;
    int y;
}PosType;

typedef struct 
{
    int ord;
    PosType seat;
    int di;
}SelemType;

typedef struct Stack
{
    SelemType* base;
    SelemType* top;
    int Stacksize;
}SqStack;

int InitStack(SqStack *S);//初始化栈//S不是指针,只是作为参数要用指针
int DestroyStack(SqStack *S);//销毁栈
int ClearStack(SqStack *S);//清空栈
int StackEmpty(SqStack *S);//判断栈是否为空
//int StackLength(SqStack S);
int GetTop(SqStack S,SelemType* e);//提取栈顶元素
int Push(SqStack *S,SelemType e);//插入栈顶元素
int Pop(SqStack *S,SelemType *e);//删除栈顶元素
//迷宫函数
PosType NextPos(PosType seat,int di);//找到当前坐标的di方向坐标并返回
int Pass(PosType seat,int maze[sizea][sizeb]);//判断当前位置能否通过
void MarkPrint(PosType seat,int maze[sizea][sizeb]);//标记当前坐标是死路
void FootPrint(PosType seat,int maze[sizea][sizeb]);//标记当前位置已经走过


int InitStack(SqStack *S)
{
    S->base=(SelemType*)malloc(STACK_INIT_SIZE*sizeof(SelemType));
    if (S->base == NULL)
    {
        printf("空间不足!");
        exit(-1);
    }
    S->top=S->base;
    S->Stacksize=STACK_INIT_SIZE;
    return RIGHT;
}
int DestroyStack(SqStack *S)
{
    free(S->base);
    S->base = NULL;
    return RIGHT;
}
int ClearStack(SqStack *S)
{
    SelemType e;
    while(S->base!=S->top)
    {
        Pop(S,&e);
    }
    return RIGHT;
}
int StackEmpty(SqStack *S)
{
    if(S->base==S->top) return RIGHT;
    else return ERROR;
}

int Pop(SqStack *S,SelemType *e)
{
    if(S->base==S->top) return ERROR;
    *e=*(--S->top);
    return RIGHT;
}
int 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 == NULL)
        {
            printf("空间不足!");
            exit(-1);
        }
        S->Stacksize+=STACKINCREMENT;
        S->top=S->base+S->Stacksize;
    }
    *(S->top)=e;
    S->top++;
    return RIGHT;
}
PosType NextPos(PosType seat,int di)
{
    if(di==2)
    {
        seat.x++;
        return seat;
    }
    else if(di==1)
    {
        seat.y++;
        return seat;
    }
    else if(di==4)
    {
        seat.x--;
        return seat;
    }
    else if(di==3)
    {
        seat.y--;
        return seat;
    }
    else exit(ERROR);
}
int Pass(PosType seat,int maze[sizea][sizeb])
{
    if(maze[seat.x-1][seat.y-1]!=0&&maze[seat.x-1][seat.y-1]!=2&&seat.x<=sizea&&seat.y<=sizeb&&seat.x>=1&&seat.y>=1) return RIGHT;

    else return ERROR;

}
void MarkPrint(PosType seat,int maze[sizea][sizeb])
{
    if(seat.x<=sizea&&seat.y<=sizeb&&seat.x>=1&&seat.y>=1) maze[seat.x-1][seat.y-1]=0;
}
void FootPrint(PosType seat,int maze[sizea][sizeb])
{
    if(seat.x<=sizea&&seat.y<=sizeb&&seat.x>=1&&seat.y>=1) maze[seat.x-1][seat.y-1]=2;
}

//主函数:生成迷宫,设置入口出口,生成堆栈,开始找出路
//迷宫为1可以通过,为0不能通过,2为已经走过
int main()
{
    int maze[sizea][sizeb];
    int i,j,curstep;
    PosType start,end,curpos;
    SelemType e;
    SqStack MazePath;
    InitStack(&MazePath);
    printf("请输入迷宫0/1\n");
    for(i=0;i<sizea;i++)
    {
        for(j=0;j<sizeb;j++)
        {
            scanf("%d",&maze[i][j]);
        }
    }
    printf("请输入入口和出口坐标");
    scanf("%d%d%d%d",&start.x,&start.y,&end.x,&end.y);
    printf("迷宫为\n");
    for(i=0;i<sizea;i++)
    {
        for(j=0;j<sizeb;j++)
        {
            printf("%d",maze[i][j]);
            printf("\t");
        }
        printf("\n");
    }
    curpos=start;
    FootPrint(curpos, maze);//循环之前起点已经走过,则要给起点走过的标记,否则返回到起点时会以为可经过而重复
    curstep=2;
    e.seat=curpos;e.ord=1;e.di=1;
    Push(&MazePath,e);
    curpos=NextPos(curpos,e.di);
    do{
        if(Pass(curpos,maze)==1)
        { 
            FootPrint(curpos,maze);
            e.seat=curpos;e.ord=curstep;e.di=1;
            Push(&MazePath,e);
            if(curpos.x==end.x&&curpos.y==end.y) 
            {
                printf("成功找到路径!");
                break;
            }
            curpos=NextPos(curpos,e.di);
            curstep++;
        }
        else
        {
            if (!StackEmpty(&MazePath))
            {
                Pop(&MazePath, &e);
            }
            while(e.di==4&&!StackEmpty(&MazePath))
            {
                MarkPrint(e.seat,maze);
                Pop(&MazePath,&e);
                curstep--;//若要彻底删除一步,则在堆栈中的步数也要统一
            }
            if(e.di<4)
            {
                e.di++;
                curpos=NextPos(e.seat,e.di);
                Push(&MazePath,e);
            }
        }
    }while(1);
     printf("路径坐标依次为");
    i=0;
	while(i<curstep)
	{
		printf("(%d,%d)",MazePath.base[i].seat.x,MazePath.base[i].seat.y);
		i++;
	}
    DestroyStack(&MazePath);
    return 0;
    
}


注意,代码中的坐标点(x,y)采用右手坐标系顺时针旋转90度。

下面为运行结果

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值