Bird
Raised Fist0
DSA Rustprogramming~20 mins

BFS Breadth First Search on Graph in DSA Rust - Practice Problems & Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
BFS Mastery Badge
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of BFS traversal on a simple graph

What is the output of the BFS traversal starting from node 0?

DSA Rust
use std::collections::{VecDeque, HashMap};

fn bfs(graph: &HashMap<i32, Vec<i32>>, start: i32) -> Vec<i32> {
    let mut visited = std::collections::HashSet::new();
    let mut queue = VecDeque::new();
    let mut order = Vec::new();

    visited.insert(start);
    queue.push_back(start);

    while let Some(node) = queue.pop_front() {
        order.push(node);
        if let Some(neighbors) = graph.get(&node) {
            for &neighbor in neighbors {
                if !visited.contains(&neighbor) {
                    visited.insert(neighbor);
                    queue.push_back(neighbor);
                }
            }
        }
    }
    order
}

fn main() {
    let mut graph = HashMap::new();
    graph.insert(0, vec![1, 2]);
    graph.insert(1, vec![2]);
    graph.insert(2, vec![0, 3]);
    graph.insert(3, vec![3]);

    let result = bfs(&graph, 0);
    println!("{:?}", result);
}
A[0, 1, 3, 2]
B[0, 1, 2, 3]
C[0, 2, 1, 3]
D[0, 3, 2, 1]
Attempts:
2 left
💡 Hint

Remember BFS visits neighbors level by level, starting from the start node.

🧠 Conceptual
intermediate
1:30remaining
BFS queue behavior on a cyclic graph

In BFS, what prevents infinite loops when traversing a graph with cycles?

ASorting neighbors before visiting
BLimiting the depth of BFS traversal
CUsing a visited set to track already visited nodes
DUsing a stack instead of a queue
Attempts:
2 left
💡 Hint

Think about how BFS avoids revisiting the same node multiple times.

🔧 Debug
advanced
2:30remaining
Identify the error in BFS implementation

What error will this BFS code produce when run?

DSA Rust
use std::collections::{VecDeque, HashMap};

fn bfs(graph: &HashMap<i32, Vec<i32>>, start: i32) -> Vec<i32> {
    let mut visited = std::collections::HashSet::new();
    let mut queue = VecDeque::new();
    let mut order = Vec::new();

    queue.push_back(start);

    while let Some(node) = queue.pop_front() {
        order.push(node);
        if let Some(neighbors) = graph.get(&node) {
            for &neighbor in neighbors {
                if !visited.contains(&neighbor) {
                    visited.insert(neighbor);
                    queue.push_back(neighbor);
                }
            }
        }
    }
    order
}

fn main() {
    let mut graph = HashMap::new();
    graph.insert(0, vec![1, 2]);
    graph.insert(1, vec![2]);
    graph.insert(2, vec![0, 3]);
    graph.insert(3, vec![3]);

    let result = bfs(&graph, 0);
    println!("{:?}", result);
}
AThe BFS will run infinitely due to missing visited insertion for start node
BThe code will not compile due to missing semicolon
CThe BFS will return an empty vector
DThe BFS will panic due to accessing a missing key
Attempts:
2 left
💡 Hint

Check if the start node is marked visited before starting the loop.

🚀 Application
advanced
2:00remaining
Shortest path length using BFS

Given an unweighted graph, which BFS modification correctly computes the shortest path length from start to all nodes?

AMaintain a distance map updated when a node is first visited
BCount the number of nodes visited and divide by total nodes
CUse DFS instead of BFS for shortest path
DStore all paths and pick the shortest after traversal
Attempts:
2 left
💡 Hint

Think about how BFS layers correspond to distance from start.

❓ Predict Output
expert
2:30remaining
Output of BFS on disconnected graph

What is the output of BFS starting from node 1 on this disconnected graph?

DSA Rust
use std::collections::{VecDeque, HashMap};

fn bfs(graph: &HashMap<i32, Vec<i32>>, start: i32) -> Vec<i32> {
    let mut visited = std::collections::HashSet::new();
    let mut queue = VecDeque::new();
    let mut order = Vec::new();

    visited.insert(start);
    queue.push_back(start);

    while let Some(node) = queue.pop_front() {
        order.push(node);
        if let Some(neighbors) = graph.get(&node) {
            for &neighbor in neighbors {
                if !visited.contains(&neighbor) {
                    visited.insert(neighbor);
                    queue.push_back(neighbor);
                }
            }
        }
    }
    order
}

fn main() {
    let mut graph = HashMap::new();
    graph.insert(0, vec![1]);
    graph.insert(1, vec![]);
    graph.insert(2, vec![3]);
    graph.insert(3, vec![]);

    let result = bfs(&graph, 1);
    println!("{:?}", result);
}
A[0, 1]
B[1, 0]
C[1, 2, 3]
D[1]
Attempts:
2 left
💡 Hint

Consider which nodes are reachable from the start node.

Practice

(1/5)
1. What does BFS (Breadth First Search) primarily use to keep track of nodes to visit next in a graph?
easy
A. A hash map
B. A stack data structure
C. A priority queue
D. A queue data structure

Solution

  1. Step 1: Understand BFS traversal method

    BFS explores nodes level by level, visiting all neighbors before moving deeper.
  2. Step 2: Identify the data structure used

    To achieve level order traversal, BFS uses a queue to process nodes in the order they are discovered.
  3. Final Answer:

    A queue data structure -> Option D
  4. Quick Check:

    BFS uses queue = C [OK]
Hint: BFS uses queue to explore neighbors level-wise [OK]
Common Mistakes:
  • Confusing BFS with DFS which uses stack
  • Thinking BFS uses priority queue
  • Assuming BFS uses hash map for traversal order
2. Which of the following Rust code snippets correctly initializes a queue for BFS traversal using the standard library?
easy
A. let mut queue = HashMap::new();
B. let mut queue = Vec::new();
C. let mut queue = VecDeque::new();
D. let mut queue = BinaryHeap::new();

Solution

  1. Step 1: Identify the correct queue type in Rust

    Rust's standard library provides VecDeque for efficient queue operations (push_back, pop_front).
  2. Step 2: Check each option

    let mut queue = VecDeque::new(); uses VecDeque::new(), which is correct. Vec is a dynamic array, not ideal for queue. HashMap and BinaryHeap are not queues.
  3. Final Answer:

    let mut queue = VecDeque::new(); -> Option C
  4. Quick Check:

    VecDeque is queue in Rust [OK]
Hint: Use VecDeque for queue in Rust BFS [OK]
Common Mistakes:
  • Using Vec which is not efficient for queue
  • Using HashMap which is for key-value pairs
  • Using BinaryHeap which is a priority queue
3. Given the following Rust code for BFS on a graph represented as adjacency list, what is the order of nodes visited starting from node 0?
use std::collections::VecDeque;

fn bfs(graph: &Vec, start: usize) -> Vec<usize> {
    let mut visited = vec![false; graph.len()];
    let mut queue = VecDeque::new();
    let mut order = Vec::new();

    visited[start] = true;
    queue.push_back(start);

    while let Some(node) = queue.pop_front() {
        order.push(node);
        for &neighbor in &graph[node] {
            if !visited[neighbor] {
                visited[neighbor] = true;
                queue.push_back(neighbor);
            }
        }
    }
    order
}

fn main() {
    let graph = vec![
        vec![1, 2],
        vec![0, 3],
        vec![0, 4],
        vec![1],
        vec![2]
    ];
    let result = bfs(&graph, 0);
    println!("{:?}", result);
}
medium
A. [0, 1, 2, 3, 4]
B. [0, 2, 1, 4, 3]
C. [0, 1, 3, 2, 4]
D. [0, 3, 1, 4, 2]

Solution

  1. Step 1: Start BFS from node 0

    Visit node 0, enqueue neighbors 1 and 2.
  2. Step 2: Visit nodes in queue order

    Dequeue 1, visit it, enqueue neighbor 3 (0 already visited). Dequeue 2, visit it, enqueue neighbor 4.
  3. Step 3: Continue visiting remaining nodes

    Dequeue 3, visit it (neighbor 1 visited). Dequeue 4, visit it (neighbor 2 visited).
  4. Final Answer:

    [0, 1, 2, 3, 4] -> Option A
  5. Quick Check:

    BFS order from 0 = [0,1,2,3,4] [OK]
Hint: BFS visits neighbors level-wise in order discovered [OK]
Common Mistakes:
  • Mixing BFS with DFS order
  • Visiting neighbors out of order
  • Forgetting to mark visited nodes
4. The following Rust BFS code has a bug causing it to panic at runtime. What is the error?
use std::collections::VecDeque;

fn bfs(graph: &Vec, start: usize) -> Vec<usize> {
    let mut visited = vec![false; graph.len()];
    let mut queue = VecDeque::new();
    let mut order = Vec::new();

    visited[start] = true;
    queue.push_back(start);

    while let Some(node) = queue.pop_front() {
        order.push(node);
        for &neighbor in &graph[node] {
            if !visited[neighbor] {
                queue.push_back(neighbor);
            }
        }
    }
    order
}

fn main() {
    let graph = vec![
        vec![1, 2],
        vec![0, 3],
        vec![0, 4],
        vec![1],
        vec![2]
    ];
    let result = bfs(&graph, 0);
    println!("{:?}", result);
}
medium
A. Missing visited[neighbor] = true; causes infinite loop
B. Queue is not initialized properly
C. Graph adjacency list is empty
D. Start node index is out of bounds

Solution

  1. Step 1: Analyze BFS loop and visited marking

    The code pushes neighbors to queue but never marks them visited.
  2. Step 2: Understand consequence of missing visited update

    Without marking visited, neighbors get re-added repeatedly causing infinite loop or panic.
  3. Final Answer:

    Missing visited[neighbor] = true; causes infinite loop -> Option A
  4. Quick Check:

    Mark visited before enqueue = prevent infinite loop [OK]
Hint: Always mark visited before enqueueing neighbors [OK]
Common Mistakes:
  • Forgetting to mark nodes visited before enqueue
  • Assuming queue initialization causes panic
  • Ignoring start node validity
5. You want to find the shortest path length from node 0 to node 4 in an unweighted graph using BFS. Which modification to the BFS code below will correctly compute the shortest distance?
use std::collections::VecDeque;

fn shortest_path_length(graph: &Vec, start: usize, target: usize) -> Option<usize> {
    let mut visited = vec![false; graph.len()];
    let mut distance = vec![0; graph.len()];
    let mut queue = VecDeque::new();

    visited[start] = true;
    queue.push_back(start);

    while let Some(node) = queue.pop_front() {
        if node == target {
            return Some(distance[node]);
        }
        for &neighbor in &graph[node] {
            if !visited[neighbor] {
                visited[neighbor] = true;
                queue.push_back(neighbor);
                // What to add here?
            }
        }
    }
    None
}

fn main() {
    let graph = vec![
        vec![1, 2],
        vec![0, 3],
        vec![0, 4],
        vec![1],
        vec![2]
    ];
    let result = shortest_path_length(&graph, 0, 4);
    println!("{:?}", result);
}
hard
A. distance[neighbor] = 1;
B. distance[neighbor] = distance[node] + 1;
C. distance[neighbor] += 1;
D. distance[neighbor] = distance[node];

Solution

  1. Step 1: Understand BFS distance tracking

    Distance to neighbor is distance to current node plus one edge.
  2. Step 2: Choose correct distance update

    Assign distance[neighbor] = distance[node] + 1 to track shortest path length.
  3. Final Answer:

    distance[neighbor] = distance[node] + 1; -> Option B
  4. Quick Check:

    Distance increments by 1 per edge [OK]
Hint: Set neighbor distance = current node distance + 1 [OK]
Common Mistakes:
  • Not updating distance correctly
  • Using += 1 without initialization
  • Setting distance to constant 1 always
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard