The Breadth First Search (BFS) algorithm is used to search a graph data structure for a node that meets a set of criteria. It starts at the root of the graph and visits all nodes at the current depth level before moving on to the nodes at the next depth level.
Relation between BFS for Graph and Tree traversal:
Breadth-First Traversal (or Search) for a graph is similar to the Breadth-First Traversal of a tree.
The only catch here is, that, unlike trees, graphs may contain cycles, so we may come to the same node again. To avoid processing a node more than once, we divide the vertices into two categories:
A boolean visited array is used to mark the visited vertices. For simplicity, it is assumed that all vertices are reachable from the starting vertex. BFS uses a queue data structure for traversal.
How does BFS work?
Starting from the root, all the nodes at a particular level are visited first and then the nodes of the next level are traversed till all the nodes are visited.
To do this a queue is used. All the adjacent unvisited nodes of the current level are pushed into the queue and the nodes of the current level are marked visited and popped from the queue.
Illustration:
Let us understand the working of the algorithm with the help of the following example.
Step1: Initially queue and visited arrays are empty.
Queue and visited arrays are empty initially.
Step2: Push node 0 into queue and mark it visited.
Push node 0 into queue and mark it visited.
Step 3: Remove node 0 from the front of queue and visit the unvisited neighbours and push them into queue.
Remove node 0 from the front of queue and visited the unvisited neighbours and push into queue.
Step 4: Remove node 1 from the front of queue and visit the unvisited neighbours and push them into queue.
Remove node 1 from the front of queue and visited the unvisited neighbours and push
Step 5: Remove node 2 from the front of queue and visit the unvisited neighbours and push them into queue.
Remove node 2 from the front of queue and visit the unvisited neighbours and push them into queue.
Step 6: Remove node 3 from the front of queue and visit the unvisited neighbours and push them into queue.
As we can see that every neighbours of node 3 is visited, so move to the next node that are in the front of the queue.
Remove node 3 from the front of queue and visit the unvisited neighbours and push them into queue.
Steps 7: Remove node 4 from the front of queue and visit the unvisited neighbours and push them into queue.
As we can see that every neighbours of node 4 are visited, so move to the next node that is in the front of the queue.
Remove node 4 from the front of queue and visit the unvisited neighbours and push them into queue.
Now, Queue becomes empty, So, terminate these process of iteration.
Implementation of BFS for Graph using Adjacency List:
C
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTICES 50
typedef struct Graph_t {
int V;
bool adj[MAX_VERTICES][MAX_VERTICES];
} Graph;
Graph* Graph_create( int V)
{
Graph* g = malloc ( sizeof (Graph));
g->V = V;
for ( int i = 0; i < V; i++) {
for ( int j = 0; j < V; j++) {
g->adj[i][j] = false ;
}
}
return g;
}
void Graph_destroy(Graph* g) { free (g); }
void Graph_addEdge(Graph* g, int v, int w)
{
g->adj[v][w] = true ;
}
void Graph_BFS(Graph* g, int s)
{
bool visited[MAX_VERTICES];
for ( int i = 0; i < g->V; i++) {
visited[i] = false ;
}
int queue[MAX_VERTICES];
int front = 0, rear = 0;
visited[s] = true ;
queue[rear++] = s;
while (front != rear) {
s = queue[front++];
printf ( "%d " , s);
for ( int adjacent = 0; adjacent < g->V;
adjacent++) {
if (g->adj[s][adjacent] && !visited[adjacent]) {
visited[adjacent] = true ;
queue[rear++] = adjacent;
}
}
}
}
int main()
{
Graph* g = Graph_create(4);
Graph_addEdge(g, 0, 1);
Graph_addEdge(g, 0, 2);
Graph_addEdge(g, 1, 2);
Graph_addEdge(g, 2, 0);
Graph_addEdge(g, 2, 3);
Graph_addEdge(g, 3, 3);
printf ( "Following is Breadth First Traversal "
"(starting from vertex 2) \n" );
Graph_BFS(g, 2);
Graph_destroy(g);
return 0;
}
|
C++
#include <bits/stdc++.h>
using namespace std;
class Graph {
int V;
vector<list< int > > adj;
public :
Graph( int V);
void addEdge( int v, int w);
void BFS( int s);
};
Graph::Graph( int V)
{
this ->V = V;
adj.resize(V);
}
void Graph::addEdge( int v, int w)
{
adj[v].push_back(w);
}
void Graph::BFS( int s)
{
vector< bool > visited;
visited.resize(V, false );
list< int > queue;
visited[s] = true ;
queue.push_back(s);
while (!queue.empty()) {
s = queue.front();
cout << s << " " ;
queue.pop_front();
for ( auto adjacent : adj[s]) {
if (!visited[adjacent]) {
visited[adjacent] = true ;
queue.push_back(adjacent);
}
}
}
}
int main()
{
Graph g(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(2, 0);
g.addEdge(2, 3);
g.addEdge(3, 3);
cout << "Following is Breadth First Traversal "
<< "(starting from vertex 2) \n" ;
g.BFS(2);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class Graph {
private int V;
private LinkedList<Integer> adj[];
Graph( int v)
{
V = v;
adj = new LinkedList[v];
for ( int i = 0 ; i < v; ++i)
adj[i] = new LinkedList();
}
void addEdge( int v, int w) { adj[v].add(w); }
void BFS( int s)
{
boolean visited[] = new boolean [V];
LinkedList<Integer> queue
= new LinkedList<Integer>();
visited[s] = true ;
queue.add(s);
while (queue.size() != 0 ) {
s = queue.poll();
System.out.print(s + " " );
Iterator<Integer> i = adj[s].listIterator();
while (i.hasNext()) {
int n = i.next();
if (!visited[n]) {
visited[n] = true ;
queue.add(n);
}
}
}
}
public static void main(String args[])
{
Graph g = new Graph( 4 );
g.addEdge( 0 , 1 );
g.addEdge( 0 , 2 );
g.addEdge( 1 , 2 );
g.addEdge( 2 , 0 );
g.addEdge( 2 , 3 );
g.addEdge( 3 , 3 );
System.out.println(
"Following is Breadth First Traversal "
+ "(starting from vertex 2)" );
g.BFS( 2 );
}
}
|
Python3
from collections import defaultdict
class Graph:
def __init__( self ):
self .graph = defaultdict( list )
def addEdge( self , u, v):
self .graph[u].append(v)
def BFS( self , s):
visited = [ False ] * ( max ( self .graph) + 1 )
queue = []
queue.append(s)
visited[s] = True
while queue:
s = queue.pop( 0 )
print (s, end = " " )
for i in self .graph[s]:
if visited[i] = = False :
queue.append(i)
visited[i] = True
if __name__ = = '__main__' :
g = Graph()
g.addEdge( 0 , 1 )
g.addEdge( 0 , 2 )
g.addEdge( 1 , 2 )
g.addEdge( 2 , 0 )
g.addEdge( 2 , 3 )
g.addEdge( 3 , 3 )
print ( "Following is Breadth First Traversal"
" (starting from vertex 2)" )
g.BFS( 2 )
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
class Graph {
private int _V;
LinkedList< int >[] _adj;
public Graph( int V)
{
_adj = new LinkedList< int >[ V ];
for ( int i = 0; i < _adj.Length; i++) {
_adj[i] = new LinkedList< int >();
}
_V = V;
}
public void AddEdge( int v, int w)
{
_adj[v].AddLast(w);
}
public void BFS( int s)
{
bool [] visited = new bool [_V];
for ( int i = 0; i < _V; i++)
visited[i] = false ;
LinkedList< int > queue = new LinkedList< int >();
visited[s] = true ;
queue.AddLast(s);
while (queue.Any()) {
s = queue.First();
Console.Write(s + " " );
queue.RemoveFirst();
LinkedList< int > list = _adj[s];
foreach ( var val in list)
{
if (!visited[val]) {
visited[val] = true ;
queue.AddLast(val);
}
}
}
}
static void Main( string [] args)
{
Graph g = new Graph(4);
g.AddEdge(0, 1);
g.AddEdge(0, 2);
g.AddEdge(1, 2);
g.AddEdge(2, 0);
g.AddEdge(2, 3);
g.AddEdge(3, 3);
Console.Write( "Following is Breadth First "
+ "Traversal(starting from "
+ "vertex 2) \n" );
g.BFS(2);
}
}
|
Javascript
class Graph
{
constructor(v)
{
this .V = v;
this .adj = new Array(v);
for (let i = 0; i < v; i++)
this .adj[i] = [];
}
addEdge(v, w)
{
this .adj[v].push(w);
}
BFS(s)
{
let visited = new Array( this .V);
for (let i = 0; i < this .V; i++)
visited[i] = false ;
let queue=[];
visited[s]= true ;
queue.push(s);
while (queue.length>0)
{
s = queue[0];
console.log(s+ " " );
queue.shift();
this .adj[s].forEach((adjacent,i) => {
if (!visited[adjacent])
{
visited[adjacent]= true ;
queue.push(adjacent);
}
});
}
}
}
g = new Graph(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(2, 0);
g.addEdge(2, 3);
g.addEdge(3, 3);
console.log( "Following is Breadth First Traversal " +
"(starting from vertex 2) " );
g.BFS(2);
|
Output
Following is Breadth First Traversal (starting from vertex 2)
2 0 3 1
Time Complexity: O(V+E), where V is the number of nodes and E is the number of edges.
Auxiliary Space: O(V)
Problems related to BFS:
What else you can read?
Please write comments if you find anything incorrect, or if you want to share more information about the topic discussed above.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!