迷宫求解C语言栈实现

迷宫求解

  1. 核心代码解析

栈中存放的数据可以理解为上一个可以通行的格子,因为在递归的时候当一个格子遇到能通行的方向的时候就不再尝试其他方向了,所以当一个格子弹出的时候,就意味着回到了弹出的这个坐标上边。

bool findPath(Maze* maze, ArrList pArr)
 {
	 direct[0].incX = 0;
	 direct[0].incY = 1;
	 direct[1].incX = 1;
	 direct[1].incY = 0;
	 direct[2].incX = 0;
	 direct[2].incY = -1;
	 direct[3].incX = -1;
	 direct[3].incY = 0;

	 Box temp;
	 int x, y, di;//存放当前的坐标和方向
	 int line, col;//存放下一个能移动的坐标和方向
	 maze->map[1][1] = -1;//首先把第一个点置-1放入栈中
	 temp.x = 1;
	 temp.y = 1;
	 temp.di = -1;//这里让第一次时候方向为-1方便在迭代过程中+1的操作
	 push(pArr,temp);
	 while (!is_empty(pArr))//当栈里存放不为空的时候进行迭代
	 {
		 temp = pop(pArr);
		 x = temp.x;
		 y = temp.y;
		 di = temp.di+1;
		 while (di < 4)
		 {
			 line = x + direct[di].incX;//这里是下一个将要移动的点。
			 col = y + direct[di].incY;
			 if (maze->map[line][col] == 0)
			 {
				 temp.x = x;
				 temp.y = y;
				 temp.di = di;
				 push(pArr, temp);//将能通行的通道压入栈中
				 x = line;//存入下一个点的信息
				 y = col;
				 maze->map[line][col] = -1;
				 if (x == 4 && y == 4)//检查是否到达终点
					 return true;
				 else
					 di = 0;
			 }
			 else
				 di++;//四种方向
		 }
	 }
	 return false;
 }
  1. 源代码

注意:这里自己手写栈一定要注意数据类型,可以使用c++或者java里面现成的数据结构。

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

typedef struct {
	int incX, incY;
}Direction;

typedef struct Maze {
	int map[10][10];//为了方便我们对地图的控制,这里设置两个全局的行、列
}Maze;

typedef struct
{
	int x, y;
	int di;
}Box;

typedef struct arr
{
	Box* pBase;
	int len;
	int top;
}Arr,*ArrList;

Direction direct[4]{};

 ArrList init_Arr(int length)
{
	 ArrList pArr = (ArrList)malloc(sizeof(Arr));
	 pArr->pBase = (Box*)malloc(sizeof(Box)*length);
	 pArr->len = length;
	 pArr->top = 0;
	 return pArr;
}

 bool is_empty(ArrList pArr)
 {
	 if (pArr->top==0)
		 return true;
	 else
		 return false;
 }

 bool is_full(ArrList pArr)
 {
	 if (pArr->len == pArr->top)
		 return true;
	 else
		 return false;
 }

 void push(ArrList pArr,Box val)
 {
	 if (is_full(pArr))
	 {
		 printf("栈满了");
		 exit(-1);
	 }
	 else
	 {
		 pArr->pBase[pArr->top] = val;
		 pArr->top++;
	 }
 }

 Box pop(ArrList pArr)
 {
	 Box val;
	 if (is_empty(pArr))
	 {
		 printf("栈空了");
		 exit(-1);
	 }
	 else
	 {
		 val = pArr->pBase[pArr->top-1];
		 pArr->top--;
	 }
	 return val;
 }

 void show(ArrList pArr)
 {
	 for (int i = 0; i < pArr->top; ++i)
	 {
		 printf("所处位置为(%d,%d),方向为%d\n",pArr->pBase[i].x,pArr->pBase[i].y,pArr->pBase[i].di);
	 }
 }

 Maze* create_maze()
 {
	 Maze* maze = (Maze*)malloc(sizeof(Maze));
	 int map[6][6] = {
			{1,1,1,1,1,1},
			{1,0,0,0,0,1},
			{1,1,0,1,1,1},
			{1,1,0,0,1,1},
			{1,0,0,0,0,1},
			{1,1,1,1,1,1}
	 };
	 for (int i = 0; i < 6; ++i)
	 {
		 for (int j = 0; j < 6; ++j)
		 {
			 maze->map[i][j] = map[i][j];
		 }
	 }
	 return maze;
 }

 bool findPath(Maze* maze, ArrList pArr)
 {
	 direct[0].incX = 0;
	 direct[0].incY = 1;
	 direct[1].incX = 1;
	 direct[1].incY = 0;
	 direct[2].incX = 0;
	 direct[2].incY = -1;
	 direct[3].incX = -1;
	 direct[3].incY = 0;

	 Box temp;
	 int x, y, di;
	 int line, col;
	 maze->map[1][1] = -1;
	 temp.x = 1;
	 temp.y = 1;
	 temp.di = -1;
	 push(pArr,temp);
	 while (!is_empty(pArr))
	 {
		 temp = pop(pArr);
		 x = temp.x;
		 y = temp.y;
		 di = temp.di+1;
		 while (di < 4)
		 {
			 line = x + direct[di].incX;
			 col = y + direct[di].incY;
			 if (maze->map[line][col] == 0)
			 {
				 temp.x = x;
				 temp.y = y;
				 temp.di = di;
				 push(pArr, temp);
				 x = line;
				 y = col;
				 maze->map[line][col] = -1;
				 if (x == 4 && y == 4)
					 return true;
				 else
					 di = 0;
			 }
			 else
				 di++;
		 }
	 }
	 return false;
 }

int main()
{
	ArrList pArr = init_Arr(20);
	Maze* maze = create_maze();
	for (int i = 0; i < 6; ++i)
	{
		for (int j = 0; j < 6; ++j)
		{
			printf("%d", maze->map[i][j]);
			if (j == 5)
				printf("\n");
		}
	}
	if (findPath(maze, pArr))
		printf("迷宫有解\n");
	else
		printf("迷宫没有解\n");
	printf("通关路径为:(右(0)下(1)左(2)上(3))");
	show(pArr);
}
  1. 结果
    在这里插入图片描述
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值