Breadth First Search (BFS) | Iterative & Recursive Implementation

来源:互联网 发布:淘宝怎么回到基础班 编辑:程序博客网 时间:2024/05/22 03:50

宽度优先搜索(BFS)|迭代和递归实现

宽度优先搜索(BFS)是用于遍历或搜索树或图形数据结构的算法。它从树根开始(或图形的某个任意节点,有时被称为“搜索关键字”),并在移动到下一级别邻居之前先探索邻居节点。

下图显示了在BFS中发现节点的顺序

这里写图片描述

宽度优先搜索(BFS)是一种图形遍历算法,它以距离源顶点的距离的顺序探索顶点,其中距离是从源顶点到节点的路径的最小长度,如上例所示。

BFS的应用 -

复制垃圾收集,切尼的算法

查找两个节点u和v之间的最短路径,其路径长度由边缘数量测量(与深度优先搜索有关的优势)

测试二分图的图形

未加权图的最小生成树

网络爬虫

在图的任何连接的组件中查找节点

Ford-Fulkerson方法,用于计算流网络中的最大流量

二进制树的序列化/反序列化与排序顺序的序列化,允许以有效的方式重新构建树。

BFS的非递归实现类似于DFS的非递归实现,但与两种不同之处在于:

它使用队列而不是堆栈
它检查在推动顶点之前是否已经发现顶点,而不是延迟该检查,直到顶点从队列中出队
迭代C ++实现BFS -
#include <bits/stdc++.h>using namespace std;//图中的顶点数#define N 15//数据结构存储图形边struct Edge {    int src, dest;};//类来表示一个图形对象class Graph{public:    //表示相邻列表的向量数组    vector<int> adjList[N];//构造函数Graph(vector<Edge> edges){       //将边缘添加到无向图    for (unsigned i = 0; i < edges.size(); i++)    {        int src = edges[i].src;        int dest = edges[i].dest;        adjList[src].push_back(dest);        adjList[dest].push_back(src);    }}};//从顶点v开始执行BFSint BFS(Graph const &graph, int v, vector<bool> &discovered){     //创建一个用于做BFS的队列    queue<int> q;   //将源顶点标记为已发现    discovered[v] = true;//将源顶点推入队列q.push(v); //运行直到队列不为空while (!q.empty()){    //从队列中弹出前端节点并打印它    v = q.front();    q.pop();    cout << v << " ";      //为每个边缘做(v - > u)    for (int u : graph.adjList[v])        if (!discovered[u])        {            //标记它发现并将其推入队列            discovered[u] = true;            q.push(u);        }}}// 主功能int main(){   //如上图所示的图形边沿向量    vector<Edge> edges = {         {1, 2}, {1, 3}, {1, 4}, {2, 5}, {2, 6}, {5, 9},         {5, 10}, {4, 7}, {4, 8}, {7, 11}, {7, 12}            //顶点13和14是单个节点    };       //从边缘创建一个图形    Graph graph(edges);      //存储顶点是否被发现    vector<bool> discovered(N); //将BFS从所有未发现的节点遍历到    //覆盖图形的所有未连接的组件    for (int i = 1; i < N; i++)        if (discovered[i] == false)            // start BFS traversal from vertex i            BFS(graph, i, discovered);    return 0;}
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14

递归C ++实现BFS -

#include <bits/stdc++.h>using namespace std;//图中的顶点数#define N 13//数据结构存储图形边struct Edge {    int src, dest;};//类来表示一个图形对象class Graph{public: //表示相邻列表的向量数组    vector<int> adjList[N];    //构造函数Graph(vector<Edge> edges){    //将边缘添加到无向图    for (unsigned i = 0; i < edges.size(); i++)    {        int src = edges[i].src;        int dest = edges[i].dest;        adjList[src].push_back(dest);        adjList[dest].push_back(src);    }}};//在图表上递归执行BFSvoid recursiveBFS(Graph const &graph, queue<int> &q,                     vector<bool> &discovered){    if (q.empty())        return;  //从队列中弹出前端节点并打印它int v = q.front();q.pop();cout << v << " ";    //为每个边缘做(v - > u)for (int u : graph.adjList[v]){    if (!discovered[u])    {           //标记它发现并将其推入队列        discovered[u] = true;        q.push(u);    }}recursiveBFS(graph, q, discovered);

}

// 主功能int main(){     //如上图所示的图形边沿向量    vector<Edge> edges = {         {1, 2}, {1, 3}, {1, 4}, {2, 5}, {2, 6}, {5, 9},         {5, 10}, {4, 7}, {4, 8}, {7, 11}, {7, 12}    }; //从边缘创建一个图形Graph graph(edges);  //存储顶点是否被发现vector<bool> discovered(N); //创建一个用于做BFS的队列queue<int> q;//将源顶点标记为已发现discovered[1] = true; //将源顶点推入队列q.push(1); //从顶点i启动BFS遍历recursiveBFS(graph, q, discovered);return 0;

}

输出:
1 2 3 4 5 6 7 8 9 10 11 12

BFS遍历的时间复杂度为O(n + m),其中n为顶点数,e为图中边缘数。 请注意,O(m)可能在O(1)和O(n2)之间变化,具体取决于图形的密度。

原创粉丝点击