迷宫求解,用顺序栈结构实现

迷宫求解的逻辑层次在这里插入图片描述

演示结果

’.’ 代表走通迷宫路线的坐标点,**’+’**代表走过但是走不通的坐标点。
在这里插入图片描述

代码部分

#include<stdio.h>
#include<stdlib.h>
#define STACK_INIT_SIZE 100//存储空间初始分配量 
#define STACKINCREMENT 10//分配增量
typedef int Status;
typedef char MazeType[11][11];//自定义 迷宫

typedef struct {//坐标
	int x;//行
	int y;//列
}PosType;
typedef struct {//作为栈sqStack的基本元素,包含以下信息 
	int ord;	 //路径的序号
	PosType seat;//坐标位置
	int di;		 //下一个通道方向(默认是东(1),东边不通的话顺时针转:南(2)西(3)北(4))
}SElemType;
typedef struct{//存储完整的路线信息 
	SElemType *base;
	SElemType *top;
	int stacksize;
}sqStack; 
Status InitStack(sqStack &s){//初始化栈 
	s.base = (SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
	if(!s.base){
		exit(1);
	}
	s.top=s.base;
	s.stacksize=STACK_INIT_SIZE;
		return 0;
}
Status Push(sqStack &s,SElemType e){//插入元素e为新的栈顶元素 

	if(s.top-s.base>=s.stacksize){//如果栈满,扩充空间 
		s.base = (SElemType *)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(SElemType));
		if(!s.base){
		exit(1);
		}
		s.top=s.base+s.stacksize; 
		s.stacksize+=STACKINCREMENT;
	}
	*s.top++=e;//赋值后栈顶指针+1 
	return 0;
}
Status Pop(sqStack &s,SElemType &e){//删除栈顶元素 
	if(s.top==s.base){
		return 1;
	}
	e = *--s.top;//栈顶指针-1,给e赋值 
	return 0;
}
Status StackEmpty(sqStack s)//判断栈是否为空 
{
	if(s.base==s.top)
		return 1;
	return 0;
}
PosType NextPos(PosType seat,int di)//其他方向的位置 
{
	PosType e;
	if(di==1)//东 
	{
		e.x = seat.x;
		e.y = seat.y+1;
	}
	if(di==2)//南 
	{
		e.x = seat.x+1;
		e.y = seat.y;
	}
	if(di==3)//西 
	{
		e.x = seat.x;
		e.y = seat.y-1;
	}
	if(di==4)//北 
	{
		e.x = seat.x-1;
		e.y = seat.y;
	}
	return e;
}
Status Pass(PosType current,MazeType maze)//该坐标位置是否可通 
{
	if(current.x>=2&&current.x<=9&&current.y>=2&&current.y<=9&&maze[current.x][current.y]==NULL)
		return 1;
	return 0;
}
void FootPrint(PosType current,MazeType maze)//留下足迹 
{
	maze[current.x][current.y] = '.';
}
void MarkPrint(PosType e,MazeType maze)//留下不可用足迹 
{
	maze[e.x][e.y] = '+';
}
void display(sqStack s){//展示路线坐标 
	int i=1;
	while(s.base<s.top){
		printf("%d (%d,%d)\n",s.base->ord,s.base->seat.x-1,s.base->seat.y-1);
		s.base++;
	}
}
Status MazePath(MazeType maze,PosType Begin,PosType End){//迷宫搜索出路 
	sqStack s; 
	int curstep = 1;
	PosType current =Begin;//初始坐标 
	InitStack(s);
	do{
		if(Pass(current,maze)){//如果当前位置可以通行 
			FootPrint(current,maze);//在图像留下足迹 		
			SElemType e;e.di=1;e.ord=curstep;e.seat=current;
			Push(s,e); 
			if(current.x==End.x&&current.y==End.y){//如果当前坐标==最终坐标,结束 
					for(int i=0;i<=10;i++)
					{
						for(int j=0;j<=10;j++)
						{
							printf("%c ",maze[i][j]);
						}
						printf("\n");
					}
					display(s);
					return 0; 
			}
			current = NextPos(current ,1);//当前位置往东边移动。。。 
			curstep++;//下一步 
		}else{//如果当前位置不可以通行 
		
			if(!StackEmpty(s))
			{
				SElemType e;
				Pop(s,e);//删除不可用元素 
				while(e.di==4&&!StackEmpty(s)){//if所有方向都不行 
					MarkPrint(e.seat,maze);//留下不能通过的痕迹,设为'+' 
					Pop(s,e);//回退一步 
				}
				if(e.di<4){//if 栈顶元素有其他方向未探索 
					e.di++;
					Push(s,e);
					current = NextPos(e.seat,e.di);
				} 
			}
		} 
		
	}while(!StackEmpty(s));
return 1;
}
int main()
{
	MazeType M ={
	  {NULL,'0','1','2','3','4','5','6','7','8',NULL},
	   {'0','#','#','#','#','#','#','#','#','#','#'},
	   {'1','#',NULL,NULL,'#',NULL,NULL,NULL,'#',NULL,'#'},
	   {'2','#',NULL,NULL,'#',NULL,NULL,NULL,'#',NULL,'#'},
	   {'3','#',NULL,NULL,NULL,NULL,'#','#',NULL,NULL,'#'},
	   {'4','#',NULL,'#','#','#',NULL,NULL,NULL,NULL,'#'},
	   {'5','#',NULL,NULL,NULL,'#',NULL,NULL,NULL,NULL,'#'},
	   {'6','#',NULL,'#',NULL,NULL,NULL,'#',NULL,NULL,'#'},
	   {'7','#',NULL,'#','#','#',NULL,'#','#',NULL,'#'},
	   {'8','#','#',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'#'},
	   {NULL,'#','#','#','#','#','#','#','#','#','#'}
				};
		PosType Begin,End;
		Begin.x = 2;
		Begin.y = 2;
		End.x=9;
		End.y = 9;
 
	if(MazePath(M,Begin,End)==0)
		printf("能到达!\n");
	else
		printf("不能到达!\n");
	
	return 0;
}
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Carry_Cui

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值