Back to Course

Data Structures and Algorithms with Java

0% Complete
0/0 Steps

Breadth First Search (BFS) is an algorithm used for traversing and searching a graph or tree data structure. It is a widely used algorithm in computer science, and it is one of the most basic algorithms used to traverse a graph. BFS is used to find the shortest paths between two nodes in a graph, and it is also used to find connected components in an undirected graph. This article will cover the fundamentals of Breadth First Search (BFS), how the algorithm works, its time complexity, and its space complexity.

Understanding Graphs

Before diving into Breadth First Search (BFS), it is important to understand what a graph is. A graph is a data structure consisting of nodes (or vertices) and edges. Nodes represent the objects in the graph, and edges represent the connections between these objects. Graphs can be undirected or directed. In an undirected graph, the edges between nodes do not have a direction, and the edges in a directed graph are directed from one node to another.

How Breadth First Search (BFS) Works

Breadth First Search (BFS) is an algorithm used for traversing and searching a graph or tree data structure. BFS works by traversing the graph in layers. It starts at the root node and explores each of the immediate neighbor nodes at the current layer before moving on to the next layer. This process is repeated until the desired node is found or all the nodes in the graph have been visited.

The algorithm begins by putting the root node in a queue and examining the neighbors of the root node. The neighbors of the root node are then added to the queue and visited in the same order they were added. As the algorithm continues, each node is visited in the order it was added to the queue. The algorithm continues until the desired node is found or all the nodes in the graph have been visited.

Time Complexity

The time complexity of Breadth First Search (BFS) is dependent on the size of the graph. 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. This means that the time complexity of BFS is linear, as the number of vertices and edges increase, the time complexity will also increase linearly.

Space Complexity

The space complexity of Breadth First Search (BFS) is also dependent on the size of the graph. The space complexity of BFS is O(V), where V is the number of vertices in the graph. This means that the space complexity of BFS is proportional to the number of vertices in the graph.

Example in Java

Now that we have an understanding of how Breadth First Search (BFS) works and its time and space complexity, we will look at an example of how to implement BFS in Java.

import java.util.LinkedList;
import java.util.Queue;

public class BFS {
  
  // Initialize a queue
  Queue<Node> queue = new LinkedList<Node>();

  // Add the root node to the queue
  queue.add(root);

  // While the queue is not empty
  while(!queue.isEmpty()) {
      // Get the first node from the queue
      Node node = queue.poll();

      // Visit the node
      visit(node);

      // Add the node's children to the queue
      for(Node child : node.getChildren()) {
          queue.add(child);
      }
  }
}

Conclusion

In conclusion, Breadth First Search (BFS) is an algorithm used for traversing and searching a graph or tree data structure. It is a widely used algorithm in computer science, and it is one of the most basic algorithms used to traverse a graph. The time complexity of BFS is O(V + E) and the space complexity is O(V), where V is the number of vertices and E is the number of edges in the graph. We have also looked at an example of how to implement BFS in Java.

Exercises

Write a Java program to implement Breadth First Search (BFS) to traverse a graph.

import java.util.LinkedList; 
import java.util.Queue; 

public class BFS { 
  // Initialize a queue 
  Queue<Node> queue = new LinkedList<Node>(); 

  // Add the root node to the queue 
  queue.add(root); 

  // While the queue is not empty 
  while(!queue.isEmpty()) { 
      // Get the first node from the queue 
      Node node = queue.poll(); 

      // Visit the node 
      visit(node); 

      // Add the node's children to the queue 
      for(Node child : node.getChildren()) { 
          queue.add(child); 
      } 
  } 
} 

Write a Java program to find the shortest path between two nodes in a graph using Breadth First Search (BFS).

import java.util.LinkedList; 
import java.util.Queue; 

public class BFS { 
  // Initialize a queue 
  Queue<Node> queue = new LinkedList<Node>(); 

  // Add the root node to the queue 
  queue.add(root); 

  // Create a list to store the shortest path 
  List<Node> shortestPath = new ArrayList<>(); 

  // While the queue is not empty 
  while(!queue.isEmpty()) { 
      // Get the first node from the queue 
      Node node = queue.poll(); 

      // If the node is the destination node, add it to the shortest path 
      if(node.getValue().equals(destination)) { 
          shortestPath.add(node); 
          break; 
      } 

      // Visit the node 
      visit(node); 

      // Add the node's children to the queue 
      for(Node child : node.getChildren()) { 
          queue.add(child); 
      } 
  } 

  // Print the shortest path 
  for(Node node : shortestPath) { 
      System.out.println(node.getValue()); 
  } 
}

Write a Java program to find the connected components in an undirected graph using Breadth First Search (BFS).

import java.util.LinkedList; 
import java.util.Queue; 
import java.util.ArrayList; 

public class BFS { 
  // Initialize a queue 
  Queue<Node> queue = new LinkedList<Node>(); 

  // Add the root node to the queue 
  queue.add(root); 

  // Create a list to store the connected components 
  List<List<Node>> components = new ArrayList<>(); 

  // While the queue is not empty 
  while(!queue.isEmpty()) { 
      // Create a list to store the connected component 
      List<Node> component = new ArrayList<>(); 

      // Get the first node from the queue 
      Node node = queue.poll(); 

      // Add the node to the connected component 
      component.add(node); 

      // Visit the node 
      visit(node); 

      // Add the node's children to the queue 
      for(Node child : node.getChildren()) { 
          queue.add(child); 
      } 

      // Add the connected component to the list of components 
      components.add(component); 
  } 

  // Print the connected components 
  for(List<Node> component : components) { 
      for(Node node : component) { 
          System.out.println(node.getValue()); 
      } 
  } 
} 

Write a Java program to find the number of nodes in a graph using Breadth First Search (BFS).

import java.util.LinkedList; 
import java.util.Queue; 

public class BFS { 
  // Initialize a queue 
  Queue<Node> queue = new LinkedList<Node>(); 

  // Add the root node to the queue 
  queue.add(root); 

  // Initialize a counter to keep track of the number of nodes 
  int count = 0; 

  // While the queue is not empty 
  while(!queue.isEmpty()) { 
      // Get the first node from the queue 
      Node node = queue.poll(); 

      // Increment the counter 
      count++; 

      // Visit the node 
      visit(node); 

      // Add the node's children to the queue 
      for(Node child : node.getChildren()) { 
          queue.add(child); 
      } 
  } 

  // Print the number of nodes 
  System.out.println("Number of nodes: " + count); 
} 

Write a Java program to find the diameter of a graph using Breadth First Search (BFS).

import java.util.LinkedList; 
import java.util.Queue; 

public class BFS { 
  // Initialize a queue 
  Queue<Node> queue = new LinkedList<Node>(); 

  // Add the root node to the queue 
  queue.add(root); 

  // Create a list to store the visited nodes 
  List<Node> visited = new ArrayList<>(); 

  // Initialize a maximum distance 
  int maxDistance = 0; 

  // While the queue is not empty 
  while(!queue.isEmpty()) { 
      // Get the first node from the queue 
      Node node = queue.poll(); 

      // Visit the node 
      visit(node); 

      // Add the node's children to the queue 
      for(Node child : node.getChildren()) { 
          queue.add(child); 

          // Calculate the distance between the node and the child 
          int distance = calculateDistance(node, child); 

          // Update the maximum distance 
          if(distance > maxDistance) { 
              maxDistance = distance; 
          } 
      } 
  } 

  // Print the diameter of the graph 
  System.out.println("Diameter of the graph: " + maxDistance); 
}