迷宫(深度搜索dfs)

首先输入一个迷宫,用0,1表示,如:m行n列的迷宫

5 4
0 0 1 0
0 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1

0表示通路,1表示障碍。

然后输入起始点的坐标和终止点的坐标,求从起点到终点最少的步数。

用dfs,代码如下:

<span style="font-size:18px;">#include<stdio.h>
int book[51][51],p[51][51];
int min=99999,endx,endy;//因为终点坐标要在dfs和主函数中使用,所以应该用全局变量
	int m,n;
void dfs(int x,int y,int step)
{
	int tx,ty;
	int next[4][4]={{0,1},{-1,0},{0,-1},{1,0}};//数组代表上下左右四个方向
	if(x==endx&&y==endy)//当起点和终点相等的时候
	{
		if(step<min)//求最小步数
		min=step;
		return;//必须要有
	}
	for(int k=0;k<=3;k++)//从上下左右四个不同的方向进行搜索
	{
		tx=x+next[k][0];
		ty=y+next[k][1];
		if(tx<0||tx>=m||ty<0||ty>=n)//超出迷宫边界时,continue
		{
			continue;
		}
		if(book[tx][ty]==0&&p[tx][ty]==0)//如果当前坐标没有被走过,并且不是障碍
		{
			book[tx][ty]=1;//把当前坐标标记为走过
			dfs(tx,ty,step+1);进行下一阶段的dfs
			book[tx][ty]=0;回溯再次搜索时释放已标记的路径
		}
	}
	return;
}
int main(void)
{

	int beginx,beginy;
	scanf("%d%d",&m,&n);//输入行和列
	for(int i=0;i<m;i++)
	for(int j=0;j<n;j++)
	{
		scanf("%d",&p[i][j]);//输入迷宫,0,1表示
	}
	scanf("%d%d%d%d",&beginx,&beginy,&endx,&endy);//输入起点和终点的坐标
	book[beginx][beginy]=1;//book是标记数组,值为1的时候,代表此坐标已经走过,因为起点已经走过,所以首先置为1
	dfs(beginx,beginy,0);当前阶段已经做完,并且一步还没有走,所以转向下一个阶段
	printf("%d\n",min);
	return 0;
}</span>


bfs代码如下:

#include<stdio.h>
struct mark{
	int x;
	int y;
	int f;
	int s;
};//因为用到队列,所以定义一个结构体
int main(void)
{
	int m,n,beginx,beginy,endx,endy,k,tx,ty,head=0,tail=0,flag=0;
	struct mark queue[2501];//结构体数组
	int biao[51][51]={0},mi[51][51];标记数组和存迷宫的数组
	int next[4][4]={{0,1},{1,0},{0,-1},{-1,0}};//方向数组
	scanf("%d%d",&m,&n);//输入迷宫的行数和列数
	for(int i=0;i<m;i++)
	for(int j=0;j<n;j++)
	{
		scanf("%d",&mi[i][j]);//输入迷宫,0代表通路,1代表障碍
	}
	scanf("%d%d%d%d",&beginx,&beginy,&endx,&endy);//输入起点和终点
	beginx-=1;//转换成数组中的下标,需要减 1
	beginx-=1;
	endx-=1;
	endy-=1;
	queue[tail].x=beginx;//先把起点入队列
	queue[tail].y=beginy;
	queue[tail].f=0;//存放当前节点的父节点(可以不要)
	queue[tail].s=0;//存放步数
	biao[beginx][beginy]=1;//把走过的标记为 1 
	tail++;//队列的尾指针向后移动一位(队列的尾指针始终指向队列最后元素的下一位)
/*此时起点已经进入队列中,接下来所要做的就是向下扩展*/
	while(head<tail)//当head和tail相同时,就表示队列中已经没有元素,就表示扩展完了所有点,但有可能不用遍历完所有点就可以遇到终点
	{
		for(k=0;k<4;k++)//从一个点开始,向四个方向扩展
		{
			tx=queue[head].x+next[k][0];
			ty=queue[head].y+next[k][1];
			if(tx<0||tx>=m||ty<0||ty>=n)//边界判定,必须是在迷宫里面
			continue;
			if(mi[tx][ty]==0&&biao[tx][ty]==0)//如果既不是障碍又没有走过,则进入队列
			{
			queue[tail].x=tx;
			queue[tail].y=ty;
			queue[tail].f=head;
			queue[tail].s=queue[head].s+1;//步数加1,也就是又进入了新的一层
			biao[tx][ty]=1;
			tail++;
			}
			if(tx==endx&&ty==endy)//如果遇到终点,退出循环
			{
				flag=1;
				break;
			}
		}
		if(flag==1)//如果遇到终点,直接退出循环,得出结果
		break;
		head++;//每次对一个节点扩展完,要转向下一个节点进行扩展
	}
	printf("%d\n",queue[tail-1].s);因为下标为tail的没有数据,所以最后一个应该是tail-1
	return 0;
}


你可能感兴趣的:(迷宫,DFS,bfs)