Bird
Raised Fist0
DSA Rustprogramming~20 mins

Enqueue Using Linked List in DSA Rust - Practice Problems & Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Linked List Queue Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output after enqueue operations?
Consider a linked list queue initially empty. We enqueue the values 10, 20, and 30 in that order. What is the printed state of the queue after these operations?
DSA Rust
struct Node {
    data: i32,
    next: Option<Box<Node>>,
}

struct Queue {
    front: Option<Box<Node>>,
    rear: *mut Node,
}

impl Queue {
    fn new() -> Self {
        Queue { front: None, rear: std::ptr::null_mut() }
    }

    fn enqueue(&mut self, val: i32) {
        let mut new_node = Box::new(Node { data: val, next: None });
        let raw_node: *mut _ = &mut *new_node;
        if self.rear.is_null() {
            self.front = Some(new_node);
            self.rear = raw_node;
        } else {
            unsafe {
                (*self.rear).next = Some(new_node);
            }
            self.rear = raw_node;
        }
    }

    fn print_queue(&self) {
        let mut current = &self.front;
        while let Some(node) = current {
            print!("{} -> ", node.data);
            current = &node.next;
        }
        print!("null\n");
    }
}

fn main() {
    let mut q = Queue::new();
    q.enqueue(10);
    q.enqueue(20);
    q.enqueue(30);
    q.print_queue();
}
A10 -> 20 -> 30 -> null
B30 -> 20 -> 10 -> null
C10 -> 20 -> null
D20 -> 30 -> null
Attempts:
2 left
💡 Hint
Remember enqueue adds to the rear of the queue, so order is preserved.
❓ Predict Output
intermediate
2:00remaining
What happens if we enqueue on an empty queue?
Given the same Queue struct, what is the printed state after enqueueing a single value 42 into an empty queue?
DSA Rust
struct Node {
    data: i32,
    next: Option<Box<Node>>,
}

struct Queue {
    front: Option<Box<Node>>,
    rear: *mut Node,
}

impl Queue {
    fn new() -> Self {
        Queue { front: None, rear: std::ptr::null_mut() }
    }

    fn enqueue(&mut self, val: i32) {
        let mut new_node = Box::new(Node { data: val, next: None });
        let raw_node: *mut _ = &mut *new_node;
        if self.rear.is_null() {
            self.front = Some(new_node);
            self.rear = raw_node;
        } else {
            unsafe {
                (*self.rear).next = Some(new_node);
            }
            self.rear = raw_node;
        }
    }

    fn print_queue(&self) {
        let mut current = &self.front;
        while let Some(node) = current {
            print!("{} -> ", node.data);
            current = &node.next;
        }
        print!("null\n");
    }
}

fn main() {
    let mut q = Queue::new();
    q.enqueue(42);
    q.print_queue();
}
A42 -> null
Bnull
C0 -> null
D42 -> 42 -> null
Attempts:
2 left
💡 Hint
Enqueue on empty queue sets front and rear to the new node.
🔧 Debug
advanced
2:30remaining
Why does this enqueue implementation cause a runtime error?
This Rust code for enqueueing in a linked list queue compiles but causes a runtime error. What is the cause?
DSA Rust
fn enqueue(&mut self, val: i32) {
    let new_node = Box::new(Node { data: val, next: None });
    if self.rear.is_null() {
        self.front = Some(new_node);
        self.rear = &mut *new_node;
    } else {
        unsafe {
            (*self.rear).next = Some(new_node);
        }
        self.rear = &mut *new_node;
    }
}
Afront pointer is overwritten incorrectly causing null dereference
Brear pointer is never updated, causing infinite loop
Cnew_node is dropped at function end, so rear points to freed memory
Dnext pointer is assigned to wrong node causing cycle
Attempts:
2 left
💡 Hint
Think about ownership and lifetimes of Box in Rust.
🧠 Conceptual
advanced
1:30remaining
What is the time complexity of enqueue in a linked list queue?
If a queue is implemented using a linked list with pointers to front and rear, what is the time complexity of the enqueue operation?
AO(n^2) quadratic time
BO(n) linear time
CO(log n) logarithmic time
DO(1) constant time
Attempts:
2 left
💡 Hint
Enqueue adds at the rear directly using a pointer.
❓ Predict Output
expert
3:00remaining
What is the queue state after mixed enqueue operations?
Given this Rust code snippet for enqueueing values 5, 15, 25, then 35, what is the printed queue state?
DSA Rust
struct Node {
    data: i32,
    next: Option<Box<Node>>,
}

struct Queue {
    front: Option<Box<Node>>,
    rear: *mut Node,
}

impl Queue {
    fn new() -> Self {
        Queue { front: None, rear: std::ptr::null_mut() }
    }

    fn enqueue(&mut self, val: i32) {
        let mut new_node = Box::new(Node { data: val, next: None });
        let raw_node: *mut _ = &mut *new_node;
        if self.rear.is_null() {
            self.front = Some(new_node);
            self.rear = raw_node;
        } else {
            unsafe {
                (*self.rear).next = Some(new_node);
            }
            self.rear = raw_node;
        }
    }

    fn print_queue(&self) {
        let mut current = &self.front;
        while let Some(node) = current {
            print!("{} -> ", node.data);
            current = &node.next;
        }
        print!("null\n");
    }
}

fn main() {
    let mut q = Queue::new();
    q.enqueue(5);
    q.enqueue(15);
    q.enqueue(25);
    q.enqueue(35);
    q.print_queue();
}
A5 -> 15 -> 35 -> 25 -> null
B5 -> 15 -> 25 -> 35 -> null
C15 -> 25 -> 35 -> null
D35 -> 25 -> 15 -> 5 -> null
Attempts:
2 left
💡 Hint
Enqueue adds at the rear, preserving order.

Practice

(1/5)
1. What does the enqueue operation do in a linked list implementation of a queue?
easy
A. Adds a new element at the beginning (head) of the linked list
B. Removes the first element from the linked list
C. Adds a new element at the end (tail) of the linked list
D. Deletes the last element from the linked list

Solution

  1. Step 1: Understand enqueue operation in queue

    Enqueue means adding an element to the queue, which is done at the end (tail) in a linked list.
  2. Step 2: Identify linked list position for enqueue

    In a linked list queue, new nodes are added at the tail to maintain FIFO order.
  3. Final Answer:

    Adds a new element at the end (tail) of the linked list -> Option C
  4. Quick Check:

    Enqueue = Add at tail [OK]
Hint: Enqueue always adds at the tail in linked list queue [OK]
Common Mistakes:
  • Confusing enqueue with dequeue operation
  • Adding new element at head instead of tail
  • Thinking enqueue removes elements
2. Which of the following Rust code snippets correctly enqueues a new node with value val into a linked list queue?
easy
A. let new_node = Box::new(Node { data: val, next: None }); tail.next = Some(new_node); tail = tail.next.as_mut().unwrap();
B. let new_node = Box::new(Node { data: val, next: None }); head = Some(new_node);
C. let new_node = Box::new(Node { data: val, next: head }); head = Some(new_node);
D. let new_node = Box::new(Node { data: val, next: None }); tail = Some(new_node);

Solution

  1. Step 1: Create new node with value and no next

    The new node is created with data = val and next = None, correct for enqueue at tail.
  2. Step 2: Link new node at tail and update tail pointer

    Setting tail.next to new_node and moving tail pointer to new_node is correct enqueue logic.
  3. Final Answer:

    let new_node = Box::new(Node { data: val, next: None }); tail.next = Some(new_node); tail = tail.next.as_mut().unwrap(); -> Option A
  4. Quick Check:

    Enqueue = add at tail and update tail [OK]
Hint: Enqueue updates tail.next and tail pointer [OK]
Common Mistakes:
  • Assigning new node to head instead of tail
  • Not updating tail pointer after enqueue
  • Linking new node's next to head (wrong for enqueue)
3. Given this Rust code snippet for enqueue operation on a linked list queue, what will be the printed queue after enqueuing values 10, 20, 30?
struct Node {
    data: i32,
    next: Option,
}

struct Queue {
    head: Option,
    tail: *mut Node,
}

impl Queue {
    fn new() -> Self {
        Queue { head: None, tail: std::ptr::null_mut() }
    }

    fn enqueue(&mut self, val: i32) {
        let mut new_node = Box::new(Node { data: val, next: None });
        let raw_node: *mut _ = &mut *new_node;
        if self.tail.is_null() {
            self.head = Some(new_node);
            self.tail = raw_node;
        } else {
            unsafe { (*self.tail).next = Some(new_node); }
            self.tail = raw_node;
        }
    }

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

fn main() {
    let mut q = Queue::new();
    q.enqueue(10);
    q.enqueue(20);
    q.enqueue(30);
    q.print_queue();
}
medium
A. 30 -> 20 -> 10 -> null
B. 10 -> 20 -> 30 -> null
C. null
D. 10 -> null

Solution

  1. Step 1: Trace enqueue calls adding nodes at tail

    Enqueue adds 10, then 20, then 30 at the tail, preserving order.
  2. Step 2: Print queue from head to tail

    Prints nodes in order: 10 -> 20 -> 30 -> null.
  3. Final Answer:

    10 -> 20 -> 30 -> null -> Option B
  4. Quick Check:

    Enqueue order preserved in print [OK]
Hint: Enqueue adds at tail, print from head shows insertion order [OK]
Common Mistakes:
  • Assuming enqueue adds at head, reversing order
  • Not updating tail pointer causing print errors
  • Printing empty queue due to wrong head initialization
4. Identify the bug in this Rust enqueue method for a linked list queue:
fn enqueue(&mut self, val: i32) {
    let new_node = Box::new(Node { data: val, next: None });
    if self.tail.is_null() {
        self.head = Some(new_node);
        self.tail = &mut *new_node;
    } else {
        unsafe { (*self.tail).next = Some(new_node); }
        self.tail = &mut *new_node;
    }
}
medium
A. Using unsafe block unnecessarily
B. Not setting new_node.next to None
C. Not updating head pointer when queue is empty
D. Assigning tail pointer to reference of new_node which is dropped after function ends

Solution

  1. Step 1: Analyze new_node lifetime

    new_node is a local variable and will be dropped after function ends, so tail pointer becomes invalid.
  2. Step 2: Understand pointer assignment issue

    Assigning tail to &mut *new_node stores pointer to dropped memory, causing undefined behavior.
  3. Final Answer:

    Assigning tail pointer to reference of new_node which is dropped after function ends -> Option D
  4. Quick Check:

    Pointer to dropped node causes bug [OK]
Hint: Tail must point to heap node, not local variable [OK]
Common Mistakes:
  • Using local variable reference for tail pointer
  • Ignoring unsafe pointer lifetime issues
  • Not updating tail pointer at all
5. You want to implement a queue using a singly linked list in Rust that supports enqueue and dequeue efficiently. Which approach correctly handles enqueue operation to maintain O(1) time complexity and safe memory management? A) Add new node at head and update head pointer. B) Add new node at tail, update tail pointer, and use Option for next pointers. C) Add new node at tail but do not update tail pointer. D) Add new node at head and update tail pointer.
hard
A. Add new node at tail, update tail pointer, and use Option for next pointers.
B. Add new node at head and update head pointer.
C. Add new node at tail but do not update tail pointer.
D. Add new node at head and update tail pointer.

Solution

  1. Step 1: Understand enqueue efficiency in linked list queue

    Enqueue must add at tail and update tail pointer to keep O(1) time complexity.
  2. Step 2: Use Option for safe memory management

    Using Option for next pointers ensures ownership and safe heap allocation in Rust.
  3. Step 3: Reject other options

    Adding at head breaks FIFO order; not updating tail pointer breaks enqueue logic.
  4. Final Answer:

    Add new node at tail, update tail pointer, and use Option for next pointers. -> Option A
  5. Quick Check:

    Enqueue at tail + safe pointers = O(1) enqueue [OK]
Hint: Enqueue at tail with Option ensures O(1) and safety [OK]
Common Mistakes:
  • Adding at head breaks queue order
  • Not updating tail pointer after enqueue
  • Using raw pointers without ownership
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