广度优先搜索(也称宽度优先搜索,缩写BFS)是连通图的一种遍历策略。它的思想是从一个顶点V0开始,辐射状地优先遍历其周围较广的区域。

BFS算法是利用队列实现的一种搜索算法,逐层向下遍历,从一个点像四周扩散(将可选节点存放于队列中,删除已被使用的节点),使用队列完成操作,通常用于最短路径的寻找。。

一般可以用它做什么呢?一个最直观经典的例子就是走迷宫,从起点开始,找出到终点的最短路程,很多最短路径算法就是基于广度优先的思想成立的。

BFS 的应用一:层序遍历

层序遍历要求我们区分每一层,也就是返回一个二维数组。而 BFS 的遍历结果是一个一维数组,无法区分每一层。

BFS 的应用二:最短路径

在二叉树中,BFS 可以实现一层一层的遍历。在图中同样如此。从源点出发,BFS 首先遍历到第一层结点,到源点的距离为 1,然后遍历到第二层结点,到源点的距离为 2…… 可以看到,用 BFS 的话,距离源点更近的点会先被遍历到,这样就能找到到某个点的最短路径了。

BFS适合此类题目:给定初始状态跟目标状态,要求从初始状态到目标状态的最短路径。

Dijkstra 算法解决的是带权最短路径问题,而我们这里关注的是无权最短路径问题。也可以看成每条边的权重都是 1。这样的最短路径问题,用 BFS 求解就行了。

BFS 的常用模板

1.如果不需要确定当前遍历到了哪一层,模板如下:

下述是伪代码,不仅可用于二叉树,可针对所有用BFS解题。

void bfs() {
 vis[] = {0}; // or set
 queue<int> pq(start_val);

 while (!pq.empty()) {
     int cur = pq.front(); 
     pq.pop();
     for (遍历cur所有的相邻节点nex) {
         if (nex节点有效 && vis[nex]==0){
             vis[nex] = 1;
             pq.push(nex)
         }
     } // end for
 } // end while
}

2.如果需要确定遍历到哪一层,模板如下:

void bfs() {
 int level = 0;
 vis[] = {0}; // or set
 queue<int> pq(original_val);
 while (!pq.empty()) {
     int sz = pq.size();

     while (sz--) {
         int cur = pq.front(); 
         pq.pop();
         for (遍历cur所有的相邻节点nex) {
             if (nex节点有效 && vis[nex] == 0) {
                 vis[nex] = 1;
                 pq.push(nex)
             }
         } // end for
     } // end inner while
     level++;

 } // end outer while
}