Exploring Graphs with Breadth-First Search (BFS) in C++
Mastering Graph Traversal: A Comprehensive Guide to Breadth-First Search (BFS) in C++
Graphs are fundamental structures in computer science, representing networks such as social connections, web pages, or city maps. One popular way to traverse graphs is through Breadth-First Search (BFS), a systematic level-by-level exploration method. This blog dives into BFS, implemented in C++, to traverse a graph and handle disconnected components.
Understanding the Code
Key Concepts
Graph Representation: The graph is represented as an adjacency matrix, where
graph[i][j]
indicates a connection between nodesi
andj
.BFS Basics: BFS uses a queue to explore all neighboring nodes of a starting vertex before moving to the next level of neighbors.
Disconnected Graphs: This implementation ensures all components of the graph are visited, even if the graph is disconnected.
Code Walkthrough
Graph Representation
The graph is initialized as an adjacency matrix:
int** graph = new int*[V];
for(int i=0;i<V;i++){
graph[i] = new int[V];
for(int j=0;j<V;j++) graph[i][j] = 0;
}
Here, V
is the number of vertices, and E
is the number of edges. The adjacency matrix is populated based on input edges.
Core BFS Logic
bfs_print
void bfs_print(int** graph, int V, int sv, int* visited){
queue<int> q;
q.push(sv);
visited[sv] = 1;
while(!q.empty()){
int t = q.front();
q.pop();
cout << t << " ";
for(int i=0;i<V;i++){
if(i == t) continue;
if(graph[t][i] && !visited[i]){
visited[i] = 1;
q.push(i);
}
}
}
}
Inputs:
graph
: Adjacency matrix of the graph.V
: Total vertices in the graph.sv
: Starting vertex for BFS.visited
: Array to track visited nodes.
How it works:
The function uses a queue to process nodes.
Starting from
sv
, it marks the node as visited and enqueues it.For each dequeued node, all unvisited neighbors are enqueued.
bfs
void bfs(int** graph, int V, int sv){
int* visited = new int[V];
for(int i=0;i<V;i++) visited[i] = 0;
for(int i=0;i<V;i++){
if(!visited[i]){
bfs_print(graph, V, i, visited);
}
}
}
Ensures all nodes, including those in disconnected components, are visited.
Calls
bfs_print
for each unvisited node.
Main Function
int main() {
int V, E;
cin >> V >> E;
int** graph = new int*[V];
for(int i=0;i<V;i++){
graph[i] = new int[V];
for(int j=0;j<V;j++) graph[i][j] = 0;
}
for(int i=0;i<E;i++){
int a, b;
cin >> a >> b;
graph[a][b] = graph[b][a] = 1;
}
bfs(graph, V, 0);
return 0;
}
Reads the number of vertices (
V
) and edges (E
).Populates the adjacency matrix with edge connections.
Calls
bfs
to traverse the graph starting from vertex 0.
Example Input/Output
Input
6 5
0 1
0 2
1 3
3 4
4 5
Output
0 1 2 3 4 5
Explanation:
- The BFS traversal starts at the vertex
0
and explores all reachable nodes.
Key Advantages
Handles Disconnected Graphs: The
bfs
function ensures even isolated components are traversed.Simple Implementation: The adjacency matrix and queue make the traversal easy to implement and debug.
Optimizations and Notes
Space Efficiency: For sparse graphs, use adjacency lists instead of matrices to save memory.
Edge Cases:
A graph with no edges.
Graphs with multiple disconnected components.
Conclusion
BFS is a versatile algorithm for graph traversal, finding applications in shortest-path problems, network analysis, and more. The above implementation serves as a strong foundation for exploring more advanced graph algorithms.
References
- Find the code for the above explanation here.