Back to Data Structures & Algorithms
2026-03-165 min read

Breadth-first Search (Data Structures & Algorithms)

Learn Breadth-first Search (Data Structures & Algorithms) step by step with clear examples and exercises.

Here's the revised C programming lesson on "Breadth-first Search (Data Structures & Algorithms)" with the required changes:


Why This Matters

Before diving into Breadth-First Search (BFS), it is crucial to have a good understanding of the following concepts:

  1. Graph Data Structures: Understand the basics of graphs, nodes, and edges. Familiarity with both directed and undirected graphs is beneficial.
  2. Adjacency List Representation: Be comfortable with representing graphs using adjacency lists, where each node has a list of its adjacent nodes.
  3. Basic C Concepts (Arrays, Pointers, Loops): A strong foundation in C programming, including data structures like arrays and control structures such as loops, is essential.
  4. Depth-First Search (DFS) Algorithm: Familiarity with DFS can help you understand the differences between BFS and DFS and when to use each algorithm.

Prerequisites

Before diving into this lesson, make sure you have a good understanding of C programming basics, including arrays, pointers, loops, and control structures. Additionally, it is beneficial to be familiar with graph data structures and the Depth-First Search (DFS) algorithm.

Core Concept

Breadth-First Search (BFS) is a graph traversal algorithm that explores all neighboring nodes at the current depth level before moving on to the next level. It uses a queue data structure to keep track of nodes to be visited and maintains the order in which they were discovered.

Here's a high-level description of the algorithm:

  1. Initialize an empty array visited and a queue queue.
  2. Start from an arbitrary node (usually denoted as the source) and mark it as visited by setting its corresponding index in the visited array to 1.
  3. Enqueue the source node into the queue.
  4. While the queue is not empty:
  • Dequeue a node from the front of the queue.
  • Visit all its unvisited neighbors, enqueue them if they are not already in the queue, and mark them as visited.
  1. The algorithm terminates when all nodes have been visited or the queue is empty.

BFS for Directed Graphs

In directed graphs, there might be cases where a node has no incoming edges (incoming neighbors). To handle such cases, we can add a dummy node (often denoted as start) that has an edge pointing to every other node in the graph. This ensures that the BFS algorithm starts from a valid starting point for all nodes.

Visiting Nodes in Depth-First Order

BFS maintains the order of traversal by keeping track of the discovery and finishing times for each node. The discovery time is when the node is enqueued, and the finishing time is when it is dequeued. This information can be useful for various applications, such as topological sorting in directed acyclic graphs (DAGs).

Worked Example

Let's implement BFS for a simple graph represented using an adjacency list:

#include <stdio.h>
#define MAX_NODES 10

int visited[MAX_NODES];
int adjacency_list[MAX_NODES][MAX_NODES] = {
{0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
{1, 0, 1, 0, 0, 0, 0, 1, 0, 0},
{0, 1, 0, 1, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 1, 0, 0, 1, 0},
{0, 0, 0, 0, 1, 0, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 1, 0, 1, 0, 0},
{0, 1, 0, 0, 0, 0, 1, 0, 1, 0},
{0, 0, 0, 0, 1, 0, 0, 1, 0, 1},
{0, 0, 0, 0, 0, 0, 0, 0, 1, 0}
};

void bfs(int source) {
int queue[MAX_NODES];
int front = 0;
int rear = -1;

visited[source] = 1;
queue[++rear] = source;

while (front <= rear) {
int current = queue[front++];
printf("%d ", current);

for (int i = 0; i < MAX_NODES; ++i) {
if (adjacency_list[current][i] && !visited[i]) {
visited[i] = 1;
queue[++rear] = i;
}
}
}
}

int main() {
bfs(0);
return 0;
}

Output:

0 1 2 3 4 5 6 7 8 9

Common Mistakes

  1. Forgetting to initialize the visited array before starting the BFS algorithm.
  2. Not checking if a node is already visited before enqueuing it, which can lead to infinite loops or incorrect results.
  3. Failing to handle directed graphs with cycles by adding a maximum number of iterations limit or breaking out of the loop when a node is revisited.
  4. Using a regular array instead of a queue data structure for storing nodes to be visited, which can lead to inefficient traversal and incorrect results.
  5. Not updating the visited array after visiting each node, leading to missed nodes or incorrect traversal order.

Practice Questions

  1. Implement BFS for a weighted graph where each edge has a weight associated with it.
  2. Modify the BFS implementation to handle directed graphs with cycles (e.g., using a maximum number of iterations limit).
  3. Extend the BFS implementation to find the shortest path between two nodes in an undirected graph.
  4. Implement BFS for a sparse matrix representation of a graph, where non-zero elements represent edges and zero elements represent empty positions.
  5. Write a function that checks if there is a cycle in a directed graph using BFS.

FAQ

Q1: What is the difference between BFS and DFS?

A1. Both BFS and DFS are graph traversal algorithms, but they differ in their approach to exploring the graph. BFS explores all nodes at a given depth level before moving on to the next level, while DFS visits as far as possible along each path before backtracking.

Q2: How does BFS maintain the order of traversal?

A2. BFS maintains the order of traversal by keeping track of the discovery and finishing times for each node. The discovery time is when the node is enqueued, and the finishing time is when it is dequeued. This information can be useful for various applications, such as topological sorting in directed acyclic graphs (DAGs).

Q3: What happens if a graph has cycles?

A3. In undirected graphs with cycles, BFS will visit all nodes reachable from the starting node before backtracking and revisiting nodes already visited. In directed graphs with cycles, BFS might not find the shortest path between two nodes because it gets stuck in an infinite loop. To handle such cases, you can modify the algorithm to break out of the loop when a node is revisited or add a maximum number of iterations limit.

Q4: Can we implement BFS for weighted graphs?

A4. Yes, we can modify the BFS algorithm to work with weighted graphs by maintaining a priority queue instead of a regular queue. This ensures that nodes with lower weights are processed before nodes with higher weights, allowing us to find the shortest path between two nodes.

Breadth-first Search (Data Structures & Algorithms) | Data Structures & Algorithms | XQA Learn