《啊哈,算法》-10-广度优先遍历-C语言编程实现(小游戏情景学习)

一、问题描述

一个迷宫中,要求从位置(1,1)到位置(p,q)的最短距离。从开始位置只能向右或者向下走。
上节我们学习了深度优先遍历,是通过函数递归实现的。
现在介绍一种方法:通过一层一层扩展的方法找到这个位置。扩展的时候每发现一个点,就将这个点加入到队列中,直到找到正确的位置。

二、思路解析及广度优先遍历

1.广度优先搜索(Breadth First Search,BFS),也叫宽度优先搜索。
2.用二维数组存储这个迷宫。
需要一个数组来记录一个点是不是已经走过。

三、代码复现

#include
//用一个结构体来实现队列 
struct note{
	int x;//横坐标
	int y;//纵坐标
	int f;//父亲在队列中的编号,本题目不要求输出路径,可以不需要f
	int s;//步数 	 
}; 

int main(){
	struct note que[2501];//因为地图大小不超过50*50,所以队列大小不会超过2501
	int a[51][51]={0};//用来存储地图 
	int book[51][51]={0};//数组book的作用是记录哪些点已经在队列中了,防止一个点被重复扩充,并全部初始化为0 
	//定义一个用于表示走的方向的数组
	//走的方向顺序是顺时针,也就是右、下、左、上 
	int next[4][2]={{0,1},//向右走
					{1,0},//向下走 
					{0,-1},//向左走
					{-1,0}}; //向上走
	int head,tail;
	int i,j,k, n, m,startx,starty,p,q,tx,ty,flag;
	
	scanf("%d %d",&n,&m);
	for(i=1;i<=n;i++)
		for(j=1;j<=m;j++)
			scanf("%d",&a[i][j]); 
	scanf("%d %d %d %d",&startx,&starty,&p,&q);//这句的作用是什么呢,就是每次读入一行四个元素的意思。是构建迷宫的重要一步 
	
	
	//队列初始化
	head=1;
	tail=1;
	//往队列中插入迷宫入口坐标
	que[tail].x=startx;	
	que[tail].y=starty;	
	que[tail].f=0;	
	que[tail].s=0;	
	tail++;
	book[startx][starty]=1;
	
	flag=0;//用来标记是否到达目的地,0表示暂时还没有到达,1表示已经到达
	//当队列不空的时候循环
	while(head<tail){
		//枚举4个方向
		for(k=0;k<=3;k++){
			//计算下一个点的坐标
			tx=que[head].x+next[k][0];
			ty=que[head].y+next[k][1]; 
			//判断是否越界
			if( tx<1 || tx>n || ty<1 || ty>m ) 
				continue;
			//判断是否是障碍物或者已经在路径中
			if(a[tx][ty]==0 && book[tx][ty]==0){
				//把这个点标记为已经走过
				//注意宽度优先搜索,每个点只入队一次,所以与深度搜索不用,不需要将book数组还原
				book[tx][ty]=1;
				//插入新的点到队列中
				que[tail].x=tx;
				que[tail].y=ty;
				//因为这个点是从head中扩展出来的,所以它的父亲是head,本题目不需要求路径,因此这一句可以省略 
				que[tail].f=head; 
				que[tail].s=que[head].s+1;//步数是父亲的步数+1 	
				tail++;//这个的 作用又是什么呢?思考... 
			} 
			//如果到达目标点了,停止扩展,任务结束,退出循环
			if(tx==p &ty==q){
				//注意下边两句话,不要把顺序写倒过来
				flag=1;
				break; 
			} 
		} 
		if(flag==1)
			break;
		head++;//注意这个地方不可以忘记,当一个点扩展结束后,head++才能对后面的点继续进行扩展 
	}
	//打印队列中末尾最后一个点(目标点)的步数
	//注意tail是指向队列队尾(即最后一位)的下一个位置,所以这里需要-1
	printf("%d",que[tail-1].s);
	getchar();
	getchar();
	return 0; 
			
} 

第一行输入5 4——》代表矩阵是5行4列
接下来输入矩阵的具体情况,1表示障碍物,0表示空地。
最后一行4个数,1,1表示迷宫入口x,y坐标;后两个为目标地址x,y对应的坐标4,3
最后输出的7就是需要的步数。
《啊哈,算法》-10-广度优先遍历-C语言编程实现(小游戏情景学习)_第1张图片

四、总结

以上就是广度优先搜索,也叫广度优先队列,一般用来求最短路径。

你可能感兴趣的:(数据结构,C语言,算法,c语言,算法,数据结构)