数据结构与算法实战 - 广度(宽度)优先搜索(BFS)

欢迎关注全是干货的公众号:JavaEdge
本文链接: https://blog.csdn.net/qq_33589510/article/details/102467236

广度优先搜索(Breadth First Search, BFS),也称为宽度优先搜索。

用一个二维数组来存储迷宫。最开始的时候小哼在迷宫(1,1)处,他可以往右/下走。

在DFS中我们的方法是,先让小哼往右边走,然后一直尝试下去,直到走不通的时候再回到这里。这样是深度优先,可以通过函数的递归实现。

现在通过另外一种方法:通过"一层一层"扩展的方法来找到小哈。
扩展时每发现一个点就将这个点加入到队列中,直至走到小哈的位置(p,q)时为止,具体如下。

最开始小哼在入口(1,1)处,一步之内可以到达的点有(1,2)和(2,1) 。

但是小晗并不在这两个点上,那小哼只能通过(1,2)和(2,1)这两点继续往下走。

  • 比如现在小哼走到了(1,2)这个点,之后他又能够到达哪些新的点呢?有(2,2)
  • 再看看通过(2,1)又可以到达哪些点呢?可以到达(2,2)和(3,1)

此时你会发现(2,2)这个点既可以从(1,2)到达,也可以从(2,1)到达,而且还都只使用了2步。为了防止一个点多次被走到,这里需要一个数组记录一个点是否己经被走到过。

此时小哼2步可以走到的点就全部走到了,有(2,2)和(3,1),可是小哈并不在这两个点上。没有别的办法,还得继续往下尝试,看看通过(2,2)和(3,1)这两个点还能到达哪些新的没有走到过的点。

  • 通过(2,2)这个点我们可以到达(2,3)和(3,2)
  • 通过(3,1)可以到达(3,2)和(4,1)

现在3步可以到达的点有(2,3)、(3,2)和(4,1),依旧没有到达小哈的所在点,我们需要重复刚才的方法,直到到达小哈所在点为止

回顾一下刚才的流程,可以用一个队列来模拟这个过程。
这里我们还是用一个结构体来实现队列

struct note {
	int x; //横坐标
	int y; //纵坐标
	int s; //步数
};

//因为图大小不超过50*50。因此队列扩展不会超过2500个int head,tail;
struct note que[2501) ;

int a[51][51] = {0}; // 存储地图 

// 数组visited的用于记录哪些点已在队列中,防止一个点被重复扩展
// 并全部初始化为0
int visited[51] [51]={0}; 

// 队列初始化, 将队列置空
head = 1;
tail = 1;
 
// 第一步将(1,1)加入队列,并标记(1,1)已经走过
que[tail].x = 1;
que[tail].y = 1;
que [tail] .s = 0; 
tail++; 
visited[1][1] = 1; 

然后从(1,1)开始,先尝试往右走到达了(1,2)

tx = que[head].x;
ty = que[head].y+1;

需要判断(1,2)是否越界

if(tx<l I I tx>n II ty<l II ty>rn) 
	continue;

再判断(1,2)是否为障碍物或者已经在路径中

if(a[tx] [ty] == 0 && visited[tx][ty] == 0) 
{
} 

如果满足上面的条件,则将(1,2)入队,井标记该点已经走过。

// 把这个点标记为已经走过
visited[tx][ty] = 1;
// 注意宽搜每个点通常情况下只入队一次,和深搜不同,不要将vistied数组还原

// 插入新的点到队列中
que[tail].x = tx; 
que[tail].y = ty;
que[tail].s = que[head).s+1;

// 步数是父亲的步数 + 1
tail++; 

接下来还要继续尝试往其他方向走
这里还是规定一个顺序,即按照顺时针的方向来尝试(也就是以右、下、左、上的顺序尝试〉
我们发现从(1,1)还是可以到达(2,1),因此也需要将(2,1)也加入队列,代码实现与刚才对(1,2)的操作是一样的

head tail x y step d 对(1,1)扩展完毕后,其实(1,1)现在对我们来说已经没有用了,此时我们将(1,1)出队。出队的操作,很简单就一句话,如下。head++; 接下来我们需要在刚才新扩展出的(1,2)和(2,1)这两个点的基础上继续向下探索。到目前为止我们己经扩展出从起点出发一步以内可以到达的所有点。因为还没有到达小哈的所在位置,所以还需要继续。(1,1)出队之后,现在队列的head正好指向了(1,2)这个点,现在我们需要通过这个点继续固

参考

啊哈!算法

猜你喜欢

转载自blog.csdn.net/qq_33589510/article/details/102467236