Breadth First Search (BFS)
Description
Breadth First Search (BFS) is a graph traversal algorithm that explores all vertices at the present depth before moving on to vertices at the next depth level. Starting from a chosen source vertex, it systematically explores the graph layer by layer, making it particularly effective for:
- Finding shortest paths in unweighted graphs
- Testing if a graph is bipartite
- Finding all nodes within one connected component
- Finding the shortest cycle in an unweighted graph
Visualization
Click on a node to start BFS traversal
How It Works
BFS works by following these steps:
- Start at a chosen vertex (root node)
- Explore all neighboring vertices at the present depth
- Move to the next level of vertices
- Repeat until all vertices have been visited
Key Characteristics
- Uses a queue data structure
- Visits vertices in layers
- Guarantees shortest path in unweighted graphs
- Complete traversal of all reachable vertices
Implementation
from collections import deque
def bfs(graph, start):
visited = set([start])
queue = deque([start])
while queue:
vertex = queue.popleft()
print(vertex, end=' ') # Process current vertex
# Add all unvisited neighbors to queue
for neighbor in graph[vertex]:
if neighbor not in visited:
visited.add(neighbor)
queue.append(neighbor)
#include <queue>
#include <vector>
#include <unordered_set>
void bfs(const vector<vector<int>>& graph, int start) {
unordered_set<int> visited;
queue<int> q;
visited.insert(start);
q.push(start);
while (!q.empty()) {
int vertex = q.front();
q.pop();
cout << vertex << " "; // Process current vertex
// Add all unvisited neighbors to queue
for (int neighbor : graph[vertex]) {
if (visited.find(neighbor) == visited.end()) {
visited.insert(neighbor);
q.push(neighbor);
}
}
}
}
public class BFS {
public void Search(Dictionary<int, List<int>> graph, int start)
{
var visited = new HashSet<int>();
var queue = new Queue<int>();
visited.Add(start);
queue.Enqueue(start);
while (queue.Count > 0)
{
int vertex = queue.Dequeue();
Console.Write($"{vertex} "); // Process current vertex
// Add all unvisited neighbors to queue
foreach (int neighbor in graph[vertex])
{
if (!visited.Contains(neighbor))
{
visited.Add(neighbor);
queue.Enqueue(neighbor);
}
}
}
}
}
Complexity Analysis
Operation | Time Complexity | Space Complexity |
---|---|---|
Worst Case | O(V + E) | O(V) |
Average Case | O(V + E) | O(V) |
Best Case | O(1) | O(1) |
Where V is the number of vertices and E is the number of edges in the graph.
Advantages and Disadvantages
Advantages
- Guarantees shortest path in unweighted graphs
- Visits vertices in order of their distance from source
- Memory efficient for sparse graphs
- Optimal for searching closest nodes first
- Simple to implement and understand
Disadvantages
- Requires more memory than DFS
- Not suitable for weighted graphs
- May be slower than DFS for deep graphs
- Queue operations can be expensive
- Not space-efficient for dense graphs
Applications
- Shortest path finding in unweighted graphs
- Web crawling
- Social networking (finding connections)
- GPS navigation systems
- Peer-to-peer networks
- Broadcasting in network