Bird
Raised Fist0
DSA Rustprogramming~20 mins

Creating a Singly Linked List from Scratch in DSA Rust - Debugging & Practice

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Singly Linked List Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output of this Rust code creating a singly linked list?
Consider the following Rust code that creates a singly linked list with three nodes containing values 10, 20, and 30 respectively. What will be printed after running this code?
DSA Rust
use std::rc::Rc;
use std::cell::RefCell;

#[derive(Debug)]
struct Node {
    value: i32,
    next: Option<Rc<RefCell<Node>>>,
}

fn main() {
    let third = Rc::new(RefCell::new(Node { value: 30, next: None }));
    let second = Rc::new(RefCell::new(Node { value: 20, next: Some(third.clone()) }));
    let first = Rc::new(RefCell::new(Node { value: 10, next: Some(second.clone()) }));

    let mut current = Some(first.clone());
    while let Some(node) = current {
        print!("{} -> ", node.borrow().value);
        current = node.borrow().next.clone();
    }
    print!("null\n");
}
A10 -> 20 -> 30 -> null
B30 -> 20 -> 10 -> null
C10 -> 20 -> null
D20 -> 30 -> null
Attempts:
2 left
💡 Hint
Trace the list starting from the first node and follow the next pointers until None.
🧠 Conceptual
intermediate
1:30remaining
What is the main advantage of using Rc> in Rust for singly linked lists?
In Rust, why do we often use Rc> to implement singly linked lists instead of just Box?
ABox<Node> allows multiple ownership but no mutability, so Rc<RefCell<Node>> is faster.
BRc<RefCell<Node>> is used to avoid memory leaks by automatically freeing nodes immediately.
CRc<RefCell<Node>> allows multiple ownership and interior mutability, enabling shared and mutable access to nodes.
DBox<Node> cannot be used for linked lists because it does not support pointers.
Attempts:
2 left
💡 Hint
Think about ownership and mutability rules in Rust and how linked lists need to share nodes.
🔧 Debug
advanced
2:00remaining
What error does this Rust code produce when creating a singly linked list?
This Rust code attempts to create a singly linked list but fails to compile. What is the error message?
DSA Rust
struct Node {
    value: i32,
    next: Option<Box<Node>>,
}

fn main() {
    let first = Node { value: 1, next: None };
    let second = Node { value: 2, next: Some(first) };
}
Aerror[E0308]: mismatched types between `Box<Node>` and `Node`
Berror[E0382]: use of moved value: `first`
Cerror[E0499]: cannot borrow `first` as mutable because it is not declared as mutable
Derror[E0277]: the trait bound `Node: Copy` is not satisfied
Attempts:
2 left
💡 Hint
Look at the type expected for next and the type provided.
🚀 Application
advanced
2:30remaining
After inserting nodes 5, 10, 15 in order, what is the linked list output?
You create an empty singly linked list and insert nodes with values 5, 10, and 15 at the end in that order. What is the printed output of the list?
DSA Rust
struct Node {
    value: i32,
    next: Option<Box<Node>>,
}

struct LinkedList {
    head: Option<Box<Node>>,
}

impl LinkedList {
    fn new() -> Self {
        LinkedList { head: None }
    }

    fn append(&mut self, val: i32) {
        let new_node = Box::new(Node { value: val, next: None });
        match self.head.as_mut() {
            None => self.head = Some(new_node),
            Some(mut node) => {
                while let Some(ref mut next_node) = node.next {
                    node = next_node;
                }
                node.next = Some(new_node);
            }
        }
    }

    fn print_list(&self) {
        let mut current = self.head.as_ref();
        while let Some(node) = current {
            print!("{} -> ", node.value);
            current = node.next.as_ref();
        }
        println!("null");
    }
}

fn main() {
    let mut list = LinkedList::new();
    list.append(5);
    list.append(10);
    list.append(15);
    list.print_list();
}
A10 -> 5 -> 15 -> null
B15 -> 10 -> 5 -> null
C5 -> 15 -> 10 -> null
D5 -> 10 -> 15 -> null
Attempts:
2 left
💡 Hint
Appending adds nodes at the end, so the order is the same as insertion.
🧠 Conceptual
expert
2:00remaining
Why is implementing a safe mutable singly linked list in Rust challenging?
Rust's ownership and borrowing rules make implementing a mutable singly linked list tricky. Which reason best explains this challenge?
ABecause Rust requires all data structures to be immutable by default.
BBecause Rust forbids multiple mutable references, but linked lists require mutable access to nodes that may be shared or moved.
CBecause Rust's garbage collector interferes with manual memory management in linked lists.
DBecause Rust does not support recursive data structures like linked lists.
Attempts:
2 left
💡 Hint
Think about Rust's borrowing rules and how linked lists need to update pointers.

Practice

(1/5)
1. What is the main purpose of a Singly Linked List in data structures?
easy
A. To store elements in a random order without any links
B. To store elements in a tree-like hierarchical structure
C. To store elements with direct access by index like an array
D. To store elements in a linear order where each element points to the next

Solution

  1. Step 1: Understand the structure of a singly linked list

    A singly linked list stores elements in nodes where each node points to the next node, forming a chain.
  2. Step 2: Compare with other data structures

    Unlike arrays, singly linked lists do not provide direct index access and unlike trees, they have a single linear chain of nodes.
  3. Final Answer:

    To store elements in a linear order where each element points to the next -> Option D
  4. Quick Check:

    Singly Linked List = Linear chain with next pointers [OK]
Hint: Remember: singly linked list nodes point only forward [OK]
Common Mistakes:
  • Confusing linked lists with arrays having direct index access
  • Thinking linked lists are hierarchical like trees
  • Assuming nodes can point backward in singly linked lists
2. Which of the following is the correct way to define a node struct for a singly linked list in Rust?
easy
A. struct Node { value: i32, next: &Node }
B. struct Node { value: i32, next: Node }
C. struct Node { value: i32, next: Option }
D. struct Node { value: i32, next: Vec<Node> }

Solution

  1. Step 1: Understand Rust ownership and pointers

    Rust requires heap allocation for recursive types like linked lists, so Box is used to own the next node.
  2. Step 2: Analyze each option

    struct Node { value: i32, next: Option } uses Option allowing for a nullable next pointer, which is correct. struct Node { value: i32, next: Node } is invalid because it causes infinite size. struct Node { value: i32, next: &Node } uses a reference without lifetime, which is invalid. struct Node { value: i32, next: Vec<Node> } uses a vector which is not suitable for singly linked list next pointer.
  3. Final Answer:

    struct Node { value: i32, next: Option } -> Option C
  4. Quick Check:

    Use Option for next pointer in Rust [OK]
Hint: Use Option for nullable next node in Rust [OK]
Common Mistakes:
  • Using direct Node type causes infinite size error
  • Using references without lifetimes for next pointer
  • Using Vec<Node> instead of a single next node pointer
3. What will be the printed output after running this Rust code that creates a singly linked list with values 1, 2, 3 and prints them?
struct Node {
    value: i32,
    next: Option,
}

fn main() {
    let third = Node { value: 3, next: None };
    let second = Node { value: 2, next: Some(Box::new(third)) };
    let first = Node { value: 1, next: Some(Box::new(second)) };

    let mut current = &first;
    while let Some(ref next_node) = current.next {
        println!("{} ->", current.value);
        current = next_node;
    }
    println!("{} -> null", current.value);
}
medium
A. 1 -> 2 -> null
B. 1 -> 2 -> 3 -> null
C. 3 -> 2 -> 1 -> null
D. Compilation error due to borrowing

Solution

  1. Step 1: Trace the linked list creation

    Nodes are created in reverse order: third (3, None), second (2, Some(third)), first (1, Some(second)). So the list is 1 -> 2 -> 3 -> null.
  2. Step 2: Follow the print loop

    The loop prints current.value followed by '->' while current.next is Some. It prints 1 ->, then 2 ->, then exits loop at 3 (next is None) and prints 3 -> null.
  3. Final Answer:

    1 -> 2 -> 3 -> null -> Option B
  4. Quick Check:

    Prints nodes in order from first to last [OK]
Hint: Trace node links from first to last for output [OK]
Common Mistakes:
  • Printing nodes in reverse order by mistake
  • Missing the last node print with 'null'
  • Confusing Option with direct node causing errors
4. Identify the error in this Rust code snippet that tries to create a singly linked list node:
struct Node {
    value: i32,
    next: Option,
}

fn main() {
    let node1 = Node { value: 1, next: None };
    let node2 = Node { value: 2, next: node1 };
}
medium
A. next field must be Option, but node1 is Node type
B. Missing semicolon after node2 declaration
C. Cannot move node1 because it is not boxed inside Option
D. No error, code compiles fine

Solution

  1. Step 1: Check the type of next field

    The next field expects an Option, but node1 is a Node, not wrapped in Box or Option.
  2. Step 2: Understand Rust type requirements

    Rust requires the next pointer to be boxed and wrapped in Option to handle ownership and nullability. Directly assigning node1 causes a type mismatch.
  3. Final Answer:

    next field must be Option, but node1 is Node type -> Option A
  4. Quick Check:

    next must be Option not Node [OK]
Hint: Match next field type exactly: Option [OK]
Common Mistakes:
  • Assigning Node directly instead of Option
  • Ignoring Rust ownership rules for recursive types
  • Assuming semicolon missing causes error here
5. You want to implement a method append to add a new node at the end of a singly linked list in Rust. Which approach correctly handles ownership and mutability to traverse and append the node?
hard
A. Use a mutable reference to Option and loop until next is None, then set next to Some(new_node)
B. Use an immutable reference to Node and assign next directly without mutability
C. Clone the entire list and add the new node at the front
D. Use unsafe pointers to bypass Rust ownership rules

Solution

  1. Step 1: Understand Rust ownership and mutability for linked lists

    To modify the list, you need a mutable reference to the next pointer (Option) to traverse and update it safely.
  2. Step 2: Analyze each option

    Use a mutable reference to Option and loop until next is None, then set next to Some(new_node) correctly uses mutable references to traverse until the end and then sets next to Some(new_node). Use an immutable reference to Node and assign next directly without mutability uses immutable reference which cannot modify. Clone the entire list and add the new node at the front clones the list which is inefficient and not appending at end. Use unsafe pointers to bypass Rust ownership rules uses unsafe code which is discouraged.
  3. Final Answer:

    Use a mutable reference to Option and loop until next is None, then set next to Some(new_node) -> Option A
  4. Quick Check:

    Mutable reference to next pointer needed for append [OK]
Hint: Traverse with mutable Option reference to append [OK]
Common Mistakes:
  • Using immutable references preventing modification
  • Trying to assign next without Option or Box
  • Using unsafe code unnecessarily
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