算法修养--广度优先搜索BFS
广度优先算法(BFS)
广度优先算法(Breadth-First Search)是在图和树领域的搜索方法,其核心思想是从一个起始点开始,访问其所有的临近节点,然后再按照相同的方式访问这些临近节点的节点,这种访问方式类似涟漪泛起,一层一层的扩散。
广度优先算法解决的问题:
- 从A点出发,有没有一条路径可以到达B点
- 如果有的话,能不能找到最短的路径。
- 图/树的遍历
广度优先算法的实现(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进行升级!
敬请期待下一篇算法学习分享!