Open In App

Breadth First Search or BFS for a Graph

Last Updated : 08 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Breadth First Search (BFS) is a fundamental graph traversal algorithm. It involves visiting all the connected nodes of a graph in a level-by-level manner. In this article, we will look into the concept of BFS and how it can be applied to graphs effectively

Breadth First Search (BFS) for a Graph:

Breadth First Search (BFS) is a graph traversal algorithm that explores all the vertices in a graph at the current depth before moving on to the vertices at the next depth level. It starts at a specified vertex and visits all its neighbors before moving on to the next level of neighbors. BFS is commonly used in algorithms for pathfinding, connected components, and shortest path problems in graphs.

Relation between BFS for Graph and BFS for Tree:

Breadth-First Traversal (BFS) 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:

  • Visited and
  • Not visited.

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.

Breadth First Search (BFS) for a Graph Algorithm:

Let’s discuss the algorithm for the BFS:

  1. Initialization: Enqueue the starting node into a queue and mark it as visited.
  2. Exploration: While the queue is not empty:
    • Dequeue a node from the queue and visit it (e.g., print its value).
    • For each unvisited neighbor of the dequeued node:
      • Enqueue the neighbor into the queue.
      • Mark the neighbor as visited.
  3. Termination: Repeat step 2 until the queue is empty.

This algorithm ensures that all nodes in the graph are visited in a breadth-first manner, starting from the starting node.

How Does the BFS Algorithm 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.

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.

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

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.

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.

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 and visit the unvisited neighbours and push ithem into 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 <iostream>
#include <queue>
#include <vector>
 
using namespace std;
 
// Function to perform Breadth First Search on a graph
// represented using adjacency list
void bfs(vector<vector<int> >& adjList, int startNode,
         vector<bool>& visited)
{
    // Create a queue for BFS
    queue<int> q;
 
    // Mark the current node as visited and enqueue it
    visited[startNode] = true;
    q.push(startNode);
 
    // Iterate over the queue
    while (!q.empty()) {
        // Dequeue a vertex from queue and print it
        int currentNode = q.front();
        q.pop();
        cout << currentNode << " ";
 
        // Get all adjacent vertices of the dequeued vertex
        // currentNode If an adjacent has not been visited,
        // then mark it visited and enqueue it
        for (int neighbor : adjList[currentNode]) {
            if (!visited[neighbor]) {
                visited[neighbor] = true;
                q.push(neighbor);
            }
        }
    }
}
 
// Function to add an edge to the graph
void addEdge(vector<vector<int> >& adjList, int u, int v)
{
    adjList[u].push_back(v);
}
 
int main()
{
    // Number of vertices in the graph
    int vertices = 5;
 
    // Adjacency list representation of the graph
    vector<vector<int> > adjList(vertices);
 
    // Add edges to the graph
    addEdge(adjList, 0, 1);
    addEdge(adjList, 0, 2);
    addEdge(adjList, 1, 3);
    addEdge(adjList, 1, 4);
    addEdge(adjList, 2, 4);
 
    // Mark all the vertices as not visited
    vector<bool> visited(vertices, false);
 
    // Perform BFS traversal starting from vertex 0
    cout << "Breadth First Traversal starting from vertex "
            "0: ";
    bfs(adjList, 0, visited);
 
    return 0;
}


C




#include <stdio.h>
#include <stdlib.h>
 
#define MAX_VERTICES 100
 
// Structure to represent a node in adjacency list
struct Node {
    int data;
    struct Node* next;
};
 
// Function to create a new node
struct Node* createNode(int data)
{
    struct Node* newNode
        = (struct Node*)malloc(sizeof(struct Node));
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}
 
// Function to add an edge to the graph
void addEdge(struct Node* adjList[], int u, int v)
{
    struct Node* newNode = createNode(v);
    newNode->next = adjList[u];
    adjList[u] = newNode;
}
 
// Function to perform Breadth First Search on a graph
// represented using adjacency list
void bfs(struct Node* adjList[], int vertices,
         int startNode, int visited[])
{
    // Create a queue for BFS
    int queue[MAX_VERTICES];
    int front = 0, rear = 0;
 
    // Mark the current node as visited and enqueue it
    visited[startNode] = 1;
    queue[rear++] = startNode;
 
    // Iterate over the queue
    while (front != rear) {
        // Dequeue a vertex from queue and print it
        int currentNode = queue[front++];
        printf("%d ", currentNode);
 
        // Get all adjacent vertices of the dequeued vertex
        // currentNode If an adjacent has not been visited,
        // then mark it visited and enqueue it
        struct Node* temp = adjList[currentNode];
        while (temp != NULL) {
            int neighbor = temp->data;
            if (!visited[neighbor]) {
                visited[neighbor] = 1;
                queue[rear++] = neighbor;
            }
            temp = temp->next;
        }
    }
}
 
int main()
{
    // Number of vertices in the graph
    int vertices = 5;
 
    // Adjacency list representation of the graph
    struct Node* adjList[vertices];
    for (int i = 0; i < vertices; ++i)
        adjList[i] = NULL;
 
    // Add edges to the graph
    addEdge(adjList, 0, 1);
    addEdge(adjList, 0, 2);
    addEdge(adjList, 1, 3);
    addEdge(adjList, 1, 4);
    addEdge(adjList, 2, 4);
 
    // Mark all the vertices as not visited
    int visited[vertices];
    for (int i = 0; i < vertices; ++i)
        visited[i] = 0;
 
    // Perform BFS traversal starting from vertex 0
    printf(
        "Breadth First Traversal starting from vertex 0: ");
    bfs(adjList, vertices, 0, visited);
 
    return 0;
}


Java




import java.util.LinkedList;
import java.util.Queue;
 
// Class to represent a graph using adjacency list
class Graph {
    int vertices;
    LinkedList<Integer>[] adjList;
 
    @SuppressWarnings("unchecked") Graph(int vertices)
    {
        this.vertices = vertices;
        adjList = new LinkedList[vertices];
        for (int i = 0; i < vertices; ++i)
            adjList[i] = new LinkedList<>();
    }
 
    // Function to add an edge to the graph
    void addEdge(int u, int v) { adjList[u].add(v); }
 
    // Function to perform Breadth First Search on a graph
    // represented using adjacency list
    void bfs(int startNode)
    {
        // Create a queue for BFS
        Queue<Integer> queue = new LinkedList<>();
        boolean[] visited = new boolean[vertices];
 
        // Mark the current node as visited and enqueue it
        visited[startNode] = true;
        queue.add(startNode);
 
        // Iterate over the queue
        while (!queue.isEmpty()) {
            // Dequeue a vertex from queue and print it
            int currentNode = queue.poll();
            System.out.print(currentNode + " ");
 
            // Get all adjacent vertices of the dequeued
            // vertex currentNode If an adjacent has not
            // been visited, then mark it visited and
            // enqueue it
            for (int neighbor : adjList[currentNode]) {
                if (!visited[neighbor]) {
                    visited[neighbor] = true;
                    queue.add(neighbor);
                }
            }
        }
    }
}
 
public class Main {
    public static void main(String[] args)
    {
        // Number of vertices in the graph
        int vertices = 5;
 
        // Create a graph
        Graph graph = new Graph(vertices);
 
        // Add edges to the graph
        graph.addEdge(0, 1);
        graph.addEdge(0, 2);
        graph.addEdge(1, 3);
        graph.addEdge(1, 4);
        graph.addEdge(2, 4);
 
        // Perform BFS traversal starting from vertex 0
        System.out.print(
            "Breadth First Traversal starting from vertex 0: ");
        graph.bfs(0);
    }
}


C#




using System;
using System.Collections.Generic;
 
// Class to represent a graph using adjacency list
class Graph {
    int vertices;
    List<int>[] adjList;
 
    public Graph(int vertices)
    {
        this.vertices = vertices;
        adjList = new List<int>[ vertices ];
        for (int i = 0; i < vertices; ++i)
            adjList[i] = new List<int>();
    }
 
    // Function to add an edge to the graph
    public void AddEdge(int u, int v) { adjList[u].Add(v); }
 
    // Function to perform Breadth First Search on a graph
    // represented using adjacency list
    public void BFS(int startNode)
    {
        // Create a queue for BFS
        Queue<int> queue = new Queue<int>();
        bool[] visited = new bool[vertices];
 
        // Mark the current node as visited and enqueue it
        visited[startNode] = true;
        queue.Enqueue(startNode);
 
        // Iterate over the queue
        while (queue.Count != 0) {
            // Dequeue a vertex from queue and print it
            int currentNode = queue.Dequeue();
            Console.Write(currentNode + " ");
 
            // Get all adjacent vertices of the dequeued
            // vertex currentNode If an adjacent has not
            // been visited, then mark it visited and
            // enqueue it
            foreach(int neighbor in adjList[currentNode])
            {
                if (!visited[neighbor]) {
                    visited[neighbor] = true;
                    queue.Enqueue(neighbor);
                }
            }
        }
    }
}
 
class MainClass {
    public static void Main(string[] args)
    {
        // Number of vertices in the graph
        int vertices = 5;
 
        // Create a graph
        Graph graph = new Graph(vertices);
 
        // Add edges to the graph
        graph.AddEdge(0, 1);
        graph.AddEdge(0, 2);
        graph.AddEdge(1, 3);
        graph.AddEdge(1, 4);
        graph.AddEdge(2, 4);
 
        // Perform BFS traversal starting from vertex 0
        Console.Write(
            "Breadth First Traversal starting from vertex 0: ");
        graph.BFS(0);
    }
}


Javascript




// Class to represent a graph using adjacency list
class Graph {
    constructor() {
        this.adjList = {};
    }
 
    // Function to add an edge to the graph
    addEdge(u, v) {
        if (!this.adjList[u]) this.adjList[u] = [];
        this.adjList[u].push(v);
    }
 
    // Function to perform Breadth First Search on a graph represented using adjacency list
    bfs(startNode) {
        // Create a queue for BFS
        const queue = [];
        const visited = new Array(Object.keys(this.adjList).length).fill(false);
 
        // Mark the current node as visited and enqueue it
        visited[startNode] = true;
        queue.push(startNode);
 
        // Iterate over the queue
        while (queue.length !== 0) {
            // Dequeue a vertex from queue and print it
            const currentNode = queue.shift();
            console.log(currentNode + " ");
 
            // Get all adjacent vertices of the dequeued vertex currentNode
            // If an adjacent has not been visited, then mark it visited and enqueue it
            for (const neighbor of this.adjList[currentNode] || []) {
                if (!visited[neighbor]) {
                    visited[neighbor] = true;
                    queue.push(neighbor);
                }
            }
        }
    }
}
 
// Create a graph
const graph = new Graph();
 
// Add edges to the graph
graph.addEdge(0, 1);
graph.addEdge(0, 2);
graph.addEdge(1, 3);
graph.addEdge(1, 4);
graph.addEdge(2, 4);
 
// Perform BFS traversal starting from vertex 0
console.log("Breadth First Traversal starting from vertex 0: ");
graph.bfs(0);


Python3




from collections import defaultdict, deque
 
# Class to represent a graph using adjacency list
 
 
class Graph:
    def __init__(self):
        self.adjList = defaultdict(list)
 
    # Function to add an edge to the graph
    def addEdge(self, u, v):
        self.adjList[u].append(v)
 
    # Function to perform Breadth First Search on a graph represented using adjacency list
    def bfs(self, startNode):
        # Create a queue for BFS
        queue = deque()
        visited = [False] * (max(self.adjList.keys()) + 1)
 
        # Mark the current node as visited and enqueue it
        visited[startNode] = True
        queue.append(startNode)
 
        # Iterate over the queue
        while queue:
            # Dequeue a vertex from queue and print it
            currentNode = queue.popleft()
            print(currentNode, end=" ")
 
            # Get all adjacent vertices of the dequeued vertex currentNode
            # If an adjacent has not been visited, then mark it visited and enqueue it
            for neighbor in self.adjList[currentNode]:
                if not visited[neighbor]:
                    visited[neighbor] = True
                    queue.append(neighbor)
 
 
# Create a graph
graph = Graph()
 
# Add edges to the graph
graph.addEdge(0, 1)
graph.addEdge(0, 2)
graph.addEdge(1, 3)
graph.addEdge(1, 4)
graph.addEdge(2, 4)
 
# Perform BFS traversal starting from vertex 0
print("Breadth First Traversal starting from vertex 0:", end=" ")
graph.bfs(0)


Output

Breadth First Traversal starting from vertex 0: 0 1 2 3 4 

Time Complexity: O(V+E), where V is the number of nodes and E is the number of edges.
Auxiliary Space: O(V)

Complexity Analysis of Breadth-First Search (BFS) Algorithm:

Time Complexity of BFS Algorithm: O(V + E)

  • BFS explores all the vertices and edges in the graph. In the worst case, it visits every vertex and edge once. Therefore, the time complexity of BFS is O(V + E), where V and E are the number of vertices and edges in the given graph.

Space Complexity of BFS Algorithm: O(V)

  • BFS uses a queue to keep track of the vertices that need to be visited. In the worst case, the queue can contain all the vertices in the graph. Therefore, the space complexity of BFS is O(V), where V and E are the number of vertices and edges in the given graph.

Applications of BFS in Graphs:

BFS has various applications in graph theory and computer science, including:

  • Shortest Path Finding: BFS can be used to find the shortest path between two nodes in an unweighted graph. By keeping track of the parent of each node during the traversal, the shortest path can be reconstructed.
  • Cycle Detection: BFS can be used to detect cycles in a graph. If a node is visited twice during the traversal, it indicates the presence of a cycle.
  • Connected Components: BFS can be used to identify connected components in a graph. Each connected component is a set of nodes that can be reached from each other.
  • Topological Sorting: BFS can be used to perform topological sorting on a directed acyclic graph (DAG). Topological sorting arranges the nodes in a linear order such that for any edge (u, v), u appears before v in the order.
  • Level Order Traversal of Binary Trees: BFS can be used to perform a level order traversal of a binary tree. This traversal visits all nodes at the same level before moving to the next level.
  • Network Routing: BFS can be used to find the shortest path between two nodes in a network, making it useful for routing data packets in network protocols.

Problems on Breadth First Search or BFS for a Graph:

S.no

Problems

Practice
1. Find the level of a given node in an Undirected Graph Link
2. Minimize maximum adjacent difference in a path from top-left to bottom-right Link
3. Minimum jump to the same value or adjacent to reach the end of an Array Link
4. Maximum coin in minimum time by skipping K obstacles along the path in Matrix Link
5. Check if all nodes of the Undirected Graph can be visited from the given Node Link
6. Minimum time to visit all nodes of a given Graph at least once Link
7. Minimize moves to the next greater element to reach the end of the Array Link
8. Shortest path by removing K walls Link
9. Minimum time required to infect all the nodes of the Binary tree Link
10. Check if destination of given Matrix is reachable with required values of cells Link

FAQs on Breadth First Search (BFS) for a Graph:

Question 1: What is BFS and how does it work?

Answer: BFS is a graph traversal algorithm that systematically explores a graph by visiting all the vertices at a given level before moving on to the next level. It starts from a starting vertex, enqueues it into a queue, and marks it as visited. Then, it dequeues a vertex from the queue, visits it, and enqueues all its unvisited neighbors into the queue. This process continues until the queue is empty.

Question 2: What are the applications of BFS?

Answer: BFS has various applications, including finding the shortest path in an unweighted graph, detecting cycles in a graph, topologically sorting a directed acyclic graph (DAG), finding connected components in a graph, and solving puzzles like mazes and Sudoku.

Question 3: What is the time complexity of BFS?

Answer: The time complexity of BFS is O(V + E), where V is the number of vertices and E is the number of edges in the graph.

Question 4: What is the space complexity of BFS?

Answer: The space complexity of BFS is O(V), as it uses a queue to keep track of the vertices that need to be visited.

Question 5: What are the advantages of using BFS?

Answer: BFS is simple to implement and efficient for finding the shortest path in an unweighted graph. It also guarantees that all the vertices in the graph are visited.

Related Articles:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads