迷宫求解
本文所用头文件:link
采用顺序存储方式
已知道迷宫入口,利用栈来解决从入口到出口的问题,此篇文章可以用来加强,对于栈的运用和理解,希望队各位读者有所帮助。
算法原理:
利用栈的特性–后入先出
使得每次路径不可行的时候都可以返原路径
定义move数组试探方向
为了简化问题,方便求出新点的坐标,将从正东开始沿顺时针进行的这4个方向的坐标增量放在一个结构数组move[4]中在 move 数组中,每个元素有两个域组成,为横坐标增量,y为纵坐标增量。
可知在迷宫中有四个方向可以走将其储存在试探方向的结构体。
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;
}
此算法亦可用递归函数:
如有疑惑请联系作者!