栈的运用--迷宫求解

迷宫求解

本文所用头文件:link
采用顺序存储方式

已知道迷宫入口,利用栈来解决从入口到出口的问题,此篇文章可以用来加强,对于栈的运用和理解,希望队各位读者有所帮助。

算法原理:

利用栈的特性–后入先出
使得每次路径不可行的时候都可以返原路径

定义move数组试探方向
为了简化问题,方便求出新点的坐标,将从正东开始沿顺时针进行的这4个方向的坐标增量放在一个结构数组move[4]中在 move 数组中,每个元素有两个域组成,为横坐标增量,y为纵坐标增量。
move数组
可知在迷宫中有四个方向可以走将其储存在试探方向的结构体。

typedef struct
{  
	int x, y;
}item;
item move[4];

这样对 move 的设计会很方便地求出从某点(x,y)按某一方向 (0u 3)到达的新点(i;j)的坐标:i=十move[v].x;j=y十move[u].y;

迷宫求解算法思想如下。

(1)栈初始化。
(2)将人口点坐标及到达该点的方向(设为一1)人栈。
(3)while(栈不空)
{
栈顶元素=>(x,y,d)
出栈;
求出下一个要试探的方向 d++;
while (还有剩余试探方向时)
{
if(d 方向可走)
则{
(x,y,d)人栈;
求新点坐标(i,j);
将新点(i,j)切换为当前点(x,y);
if((x,y)==(m,n)) 结束;
else 重置 d=0;
}
else d++;
}
}
找不到通路,结束!

代码环境:

已经有关于栈的基本头文件

本文所用头文件:链接: link
采用顺序存储方式

迷宫的墙为1 可通过的为0;
入口为(1,1) 出口为(6,8)

代码详解

#include<stdio.h>
#include"Seqstack.h"     //引用栈的头文件

如需头文件请查阅:

//定义迷宫
#define m 6					  //迷宫的实际行
#define n 8					  //迷宫的实际列

定义试探方向的结构体

//定义试探方向的结构体
typedef struct
{   /*试探方向   方便求出新的坐标    i=x+move[v].x   v=0~3  即是各个方向的增量*/
	int x, y;
}item;

定义栈元素

//定义栈元素
typedef struct
{
	int x, y, d;		    //横纵坐标及方向
}DataType;			//栈的定义仍然为PSeStack;

迷宫求解函数

//迷宫求解
int  mazepath(int maze[][n + 2], item move[], int x0, int y0)
{
	/*入口参数  迷宫数组指针 下标移动的增量数组  开始点(x0,y0) 终点(m,n)返回1表示求出路径  返回0则无路径*/
	PSeqStack S;         //定义栈指针
	DataType temp;
	int x, y, d, i, j;
	temp.x = x0; temp.y = y0; temp.d = -1;
	S = Init_SeqStack();//初始化栈
	if (!S)
	{
		printf("初始化栈失败");
		return 0;
	}
	Push_SeqStack(S, temp);                 //迷宫入口入栈
	while (!Empty_SeqStack(S))
	{
		Pop_SeqStack(S, &temp);
		x = temp.x; y = temp.y; d = temp.d + 1;
		while (d < 4)
		{										/*存在剩余方向可以搜索*/
			i = x + move[d].x; j = y + move[d].y;
			if (maze[i][j] == 0)                /*此方向可以走*/
			{
				temp.x = x;
				temp.y = y;
				temp.d = d;
				Push_SeqStack(S, temp);                  //Push_SeqStack()入栈
				x = i; y = j; maze[x][y] = -1;
				if (x == m && y == n)                     //判断是否为终点
				{
					temp.x = x;
					temp.y = y;
					temp.d = d;
					Push_SeqStack(S, temp);

					while (!Empty_SeqStack(S))
					{
						Pop_SeqStack(S, &temp);
						printf("(%d,%d)<-", temp.x, temp.y);   //打印可走的路径
					}
					Destroy_Seqstack(&S);
					return 1;
				}//
				else d = 0;                        /*方向复位  第一个方向开始探索*/
			}
			else d++;                
		}
	}
	Destroy_Seqstack(&S);      //销毁栈
	printf("无路");
	return 0;
}

代码运用

int main()
{
	int maze[m + 2][n + 2]={{1,1,1,1,1,1,1,1,1,1},      //迷宫的外层均为墙(1)入口为(1,1)出口为(6,8)
						    {1,0,1,1,1,0,1,1,1,1},
						    {1,0,0,0,0,1,1,1,1,1},
						    {1,0,1,0,0,0,0,0,1,1},
						    {1,0,1,1,1,0,0,1,1,1},
						    {1,1,0,0,1,1,0,0,0,1},
						    {1,0,1,1,0,0,1,1,0,1},
						    {1,1,1,1,1,1,1,1,1,1}};   //构建迷宫
	item move[4] = { {0,1},{1,0},{0,-1},{-1,0} };
	mazepath(maze, move, 1, 1);
	return 0;
}

此算法亦可用递归函数:
如有疑惑请联系作者!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值