算法修养--广度优先搜索BFS

广度优先算法(BFS)

**广度优先算法(Breadth-First Search)**是在图和树领域的搜索方法,其核心思想是从一个起始点开始,访问其所有的临近节点,然后再按照相同的方式访问这些临近节点的节点,这种访问方式类似涟漪泛起,一层一层的扩散。

广度优先算法解决的问题:

  1. 从A点出发,有没有一条路径可以到达B点
  2. 如果有的话,能不能找到最短的路径。
  3. 图/树的遍历

广度优先算法的实现(C++):

要遍历的图结构:

C++ 复制代码
#include <iostream>
#include <vector>
#include <queue>

using namespace std;
//Breadth-First Search广度优先遍历
//对图的遍历
//参数:要遍历的图  开始位置
void BFS(vector<vector<int>>& graph,int start)
{
    int size=graph.size();
    vector<bool> visited(size, false);
    queue<int> q;//访问队列

    visited[start]=true;
    q.push(start);

    //按照队列进行选取元素遍历
    while(!q.empty())
    {
        //取出队首的元素
        int node=q.front();
        q.pop();
        //打印
        cout<<"--->"<<node;
        //将该节点的邻居们加入待访问对象队列中
        for(int neighbor:graph[node])
        {
            if(!visited[neighbor])
            {
                q.push(neighbor);
                visited[neighbor]=true;
            }
        }
    }
}

int main() {
    cout<<"---------Breadth-First Search starting---------"<<endl;
    vector<vector<int>> graph={
            {1,2,5},
            {0, 3, 4},
            {0, 3},
            {1},
            {1,5},
            {0,4}
    };
    BFS(graph,0);
    cout<<"end"<<endl;
    return 0;
}

广度优先遍历结果次序:

接着再来谈使用BFS来找两个点之间是否有通路。(例如0号和4号)

假如0号同学某日正在刷leetcode题目,题目上说要用BFS来解决,没有学过BFS的他决定去询问好友(好友之间的关系图如上所示),0号与2号、1号和5号是好友,于是他先列了一个清单,准备按照清单逐个访问,当然在找到一个会BFS的人之前要把所有可能问的人都列入清单中。

于是0号把自己的铁哥们(2、1、5)列入清单(队列)上。

然后去访问2号哥们,2号哥们说他也不会,0号说:行,那你说你还认识谁,

于是2号的哥们被列入0号的访问清单上了(入队列)

0号询问2号未果,便查找清单上的下一个访问对象--1号,1号说自己也不会BFS,把他的朋友3号和4号的住址告诉给0号,自然这俩哥们也上了0号的访问清单。

噢,对了。0号是个做事情有条理的人,凡是被访问过的清单上的人物都被划掉了(出队列),然后他继续访问清单上的第三个朋友5,自然5号告诉他你可以去问问4号,0号说1号也跟我说过4号。

于是执着的0号继续访问朋友的朋友们(3号和4号),功夫不负有心人,最终找到4号来解决了今天的leetcode题目。

至此说明,0号和4号之间肯定有一条通路。

再谈使用BFS来找最短路径问题。

为什么0号要固执地访问完身边的朋友之后再去访问朋友的朋友呢?

自己的朋友是是属于一级关系的,0号自然希望自己可以找一个更熟悉的好友来解答问题,倘若自己以及朋友解决不了,再去考虑二级关系。

所以主打的就是一个人脉宽广~!

在找目标点出发的思想就是优先找自己身边的人,自然讲究的成本是最少的。

当然还要考虑路途的距离,路况的好坏,等各种因素,这样使得路途最近的不见得是用时最短的。

这样需要跟BFS进行升级!

敬请期待下一篇算法学习分享!