ℹ️ Select 'Choose Exercise', or randomize 'Next Random Exercise' in selected language.

Choose Exercise:
Timer 00:00
WPM --
Score --
Acc --
Correct chars --

Rust Graph BFS Traversal

Rust

Goal -- WPM

Ready
Exercise Algorithm Area
1use std::collections::{HashMap, HashSet, VecDeque};
2
3// Represents a graph using an adjacency list.
4type Graph = HashMap<usize, Vec<usize>>;
5
6/// Performs a Breadth-First Search (BFS) on a graph starting from a given node.
7///
8/// # Arguments
9///
10/// * `graph` - A reference to the graph represented as an adjacency list.
11/// * `start_node` - The node to start the BFS from.
12///
13/// # Returns
14///
15/// A `HashSet` containing all nodes reachable from the `start_node`.
16pub fn bfs(graph: &Graph, start_node: usize) -> HashSet<usize> {
17let mut visited: HashSet<usize> = HashSet::new();
18let mut queue: VecDeque<usize> = VecDeque::new();
19
20// Handle the edge case where the start node might not exist in the graph.
21if !graph.contains_key(&start_node) {
22return visited; // Return empty set if start node is invalid.
23}
24
25queue.push_back(start_node);
26visited.insert(start_node);
27
28// Process nodes in the queue until it's empty.
29while let Some(current_node) = queue.pop_front() {
30// Get neighbors of the current node, handling cases where a node might have no outgoing edges.
31if let Some(neighbors) = graph.get(&current_node) {
32for &neighbor in neighbors {
33// If the neighbor hasn't been visited yet, add it to the queue and mark as visited.
34if visited.insert(neighbor) {
35queue.push_back(neighbor);
36}
37}
38}
39}
40
41visited
42}
43
44/// Helper function to build a sample graph.
45fn build_sample_graph() -> Graph {
46let mut graph: Graph = HashMap::new();
47
48// Add edges for a connected component.
49graph.insert(0, vec![1, 2]);
50graph.insert(1, vec![0, 3, 4]);
51graph.insert(2, vec![0, 5]);
52graph.insert(3, vec![1]);
53graph.insert(4, vec![1, 5]);
54graph.insert(5, vec![2, 4]);
55
56// Add an isolated node.
57graph.insert(6, vec![]);
58
59// Add another component.
60graph.insert(7, vec![8]);
61graph.insert(8, vec![7]);
62
63graph
64}
65
66/// Main function to demonstrate BFS.
67fn main() {
68let graph = build_sample_graph();
69
70println!("BFS starting from node 0:");
71let reachable_from_0 = bfs(&graph, 0);
72println!("Reachable nodes: {:?}", reachable_from_0);
73
74println!("\nBFS starting from node 6 (isolated):");
75let reachable_from_6 = bfs(&graph, 6);
76println!("Reachable nodes: {:?}", reachable_from_6);
77
78println!("\nBFS starting from node 9 (non-existent):");
79let reachable_from_9 = bfs(&graph, 9);
80println!("Reachable nodes: {:?}", reachable_from_9);
81}
Algorithm description viewbox

Rust Graph BFS Traversal

Algorithm description:

This Rust code implements a Breadth-First Search (BFS) algorithm for a graph. BFS systematically explores a graph level by level, starting from a specified node. It's commonly used to find the shortest path in an unweighted graph, determine connectivity, or traverse tree-like structures. The implementation uses an adjacency list to represent the graph and a queue to manage nodes to visit.

Algorithm explanation:

The `bfs` function performs a Breadth-First Search on a graph. It initializes a `visited` set to keep track of explored nodes and a `queue` for nodes to visit. The algorithm starts by adding the `start_node` to both the queue and the visited set. It then iteratively dequeues a node, and for each of its unvisited neighbors, it enqueues the neighbor and marks it as visited. This process continues until the queue is empty. The time complexity is O(V + E), where V is the number of vertices and E is the number of edges, because each vertex and edge is visited at most once. The space complexity is O(V) in the worst case, for storing the visited set and the queue. Edge cases handled include an empty graph, a graph with isolated nodes, and a non-existent start node. The correctness is maintained by the invariant that all nodes at distance `d` from the start node are visited before any node at distance `d+1`.

Pseudocode:

function BFS(graph, start_node):
  visited = empty set
  queue = empty queue

  if start_node not in graph:
    return visited

  add start_node to queue
  add start_node to visited

  while queue is not empty:
    current_node = dequeue from queue
    for each neighbor of current_node:
      if neighbor is not in visited:
        add neighbor to visited
        add neighbor to queue

  return visited