Breadth-First Search, commonly known as BFS, is a fundamental algorithm used to explore graphs and trees. Unlike Depth-First Search, which dives deep into a branch before backtracking, BFS explores all neighbors of a node level by level. This approach makes BFS ideal for finding the shortest path in unweighted graphs, solving maze problems, and discovering nodes in network structures. For beginners, BFS is a great way to learn about queues, graph traversal, and systematic exploration.
Learn C Programming For Free on Windows
A beginner-friendly course that teaches real C programming using a Windows compiler. Learn arrays, pointers, functions, and file handling step by step with practical lessons.
Start Learning C ProgrammingImplementing BFS in Lua is straightforward thanks to its simple table structures and flexible loops. By learning BFS, you gain a powerful tool for analyzing networks, social graphs, or any connected structure. Understanding BFS also lays the groundwork for more advanced algorithms, such as Dijkstra’s shortest path or network flow algorithms. This article will guide you through multiple practical implementations of BFS, so you can see its versatility in action.
Program 1: BFS Using a Queue on a Simple Graph
This program demonstrates BFS using a queue to traverse a basic graph represented as an adjacency list.
-- BFS using a queue
local graph = {
A = {"B", "C"},
B = {"D", "E"},
C = {"F"},
D = {},
E = {"F"},
F = {}
}
local visited = {}
local queue = {"A"}
while #queue > 0 do
local node = table.remove(queue, 1)
if not visited[node] then
print("Visited:", node)
visited[node] = true
for _, neighbor in ipairs(graph[node]) do
table.insert(queue, neighbor)
end
end
endIn this example, BFS starts at node “A” and explores neighbors in the order they appear. The queue ensures that nodes are visited level by level, which is especially useful for finding the shortest path or performing systematic exploration. Beginners will find it easy to understand how BFS keeps track of visited nodes and handles order using a queue.
Program 2: BFS Using Recursion
Although BFS is usually iterative, it can also be implemented recursively using a queue. This approach helps beginners see how recursion can simulate iterative behavior.
-- Recursive BFS
local graph = {
A = {"B", "C"},
B = {"D", "E"},
C = {"F"},
D = {},
E = {"F"},
F = {}
}
local visited = {}
function bfsRecursive(queue)
if #queue == 0 then return end
local node = table.remove(queue, 1)
if not visited[node] then
print("Visited:", node)
visited[node] = true
for _, neighbor in ipairs(graph[node]) do
table.insert(queue, neighbor)
end
end
bfsRecursive(queue)
end
bfsRecursive({"A"})This recursive BFS example demonstrates that recursion can work with queues to achieve the same level-by-level exploration. Beginners can see how recursion keeps track of the queue while still preserving BFS behavior.
Program 3: BFS on a Weighted Graph (Ignoring Weights)
BFS can also be applied to graphs where edges have weights, even though it ignores them. This is helpful for basic traversal before moving on to weighted shortest path algorithms.
-- BFS on a weighted graph (weights ignored)
local graph = {
A = {B = 2, C = 3},
B = {D = 4, E = 1},
C = {F = 5},
D = {},
E = {F = 2},
F = {}
}
local visited = {}
local queue = {"A"}
while #queue > 0 do
local node = table.remove(queue, 1)
if not visited[node] then
print("Visited:", node)
visited[node] = true
for neighbor, _ in pairs(graph[node]) do
table.insert(queue, neighbor)
end
end
endThis example shows that BFS can traverse any graph structure, whether or not edges carry weights. Beginners can see that BFS focuses on visiting nodes systematically, and weights can be incorporated later if needed.
Program 4: BFS for Connected Components
BFS can also be used to find connected components in an undirected graph. Each BFS traversal identifies one component.
-- BFS to find connected components
local graph = {
A = {"B"},
B = {"A"},
C = {"D"},
D = {"C"},
E = {}
}
local visited = {}
function bfsComponents(startNode)
local queue = {startNode}
while #queue > 0 do
local node = table.remove(queue, 1)
if not visited[node] then
visited[node] = true
for _, neighbor in ipairs(graph[node] or {}) do
table.insert(queue, neighbor)
end
end
end
end
local count = 0
for node, _ in pairs(graph) do
if not visited[node] then
bfsComponents(node)
count = count + 1
end
end
print("Number of connected components:", count)This example shows BFS applied beyond simple traversal. Beginners learn how to use BFS to analyze graph structure and count separate clusters of connected nodes.
Program 5: BFS with Numeric Node Labels (Including Negative Numbers)
BFS works perfectly with numeric nodes, including negative values, demonstrating its flexibility.
-- BFS with numeric node labels including negatives
local graph = {
[-1] = {-2, 0},
[-2] = {-3},
[-3] = {},
[0] = {1},
[1] = {}
}
local visited = {}
local queue = {-1}
while #queue > 0 do
local node = table.remove(queue, 1)
if not visited[node] then
print("Visited:", node)
visited[node] = true
for _, neighbor in ipairs(graph[node] or {}) do
table.insert(queue, neighbor)
end
end
endThis example shows that BFS is not limited by node labels or types. Beginners see that the algorithm only requires a consistent method to track visited nodes.
Frequently Asked Questions (FAQ)
BFS often raises common questions for beginners:
Q1. What is the difference between BFS and DFS?
BFS explores nodes level by level, while DFS explores as deep as possible along a branch before backtracking.
Q2. Can BFS handle cycles?
Yes, by keeping track of visited nodes, BFS avoids revisiting and infinite loops.
Q3. When is BFS better than DFS?
BFS is ideal for finding shortest paths in unweighted graphs and exploring nodes systematically.
Q4. Can BFS be used on weighted graphs?
BFS ignores weights. For shortest paths with weights, algorithms like Dijkstra’s are used.
Q5. Is BFS suitable for trees?
Yes, BFS works naturally on trees, exploring all nodes level by level.
Conclusion
Breadth-First Search is a fundamental and versatile algorithm for exploring graphs and trees. Through iterative queues, recursion, weighted graphs, connected components, and numeric nodes, beginners can understand how BFS systematically visits nodes. Practicing these examples will strengthen your understanding of graph traversal, queues, and systematic exploration. BFS is a building block for many advanced algorithms, and mastering it opens doors to solving complex problems in networking, pathfinding, and data structures.




