Bird
Raised Fist0
DSA Rustprogramming~10 mins

Delete from End of Doubly Linked List in DSA Rust - Interactive Practice

Choose your learning style10 modes available
Practice - 5 Tasks
Answer the questions below
1fill in blank
easy

Complete the code to remove the last node from the doubly linked list.

DSA Rust
fn delete_from_end(head: &mut Option<Box<Node>>) {
    if head.is_none() {
        return;
    }
    let mut current = head.as_mut();
    while let Some(node) = current {
        if node.next.is_none() {
            node.prev.as_mut().map(|prev| prev.next = None);
            [1]
            break;
        }
        current = node.next.as_mut();
    }
}
Drag options to blanks, or click blank then click option'
Anode.prev = None
Bnode.next = None
Chead.take()
Dhead = None
Attempts:
3 left
💡 Hint
Common Mistakes
Not handling the case when the list has only one node.
Forgetting to update the previous node's next pointer.
2fill in blank
medium

Complete the code to update the previous node's next pointer when deleting the last node.

DSA Rust
fn delete_from_end(head: &mut Option<Box<Node>>) {
    if head.is_none() {
        return;
    }
    let mut current = head.as_mut();
    while let Some(node) = current {
        if node.next.is_none() {
            [1];
            break;
        }
        current = node.next.as_mut();
    }
}
Drag options to blanks, or click blank then click option'
Anode.prev.as_mut().map(|prev| prev.next = None)
Bnode.next = None
Chead = None
Dnode.prev = None
Attempts:
3 left
💡 Hint
Common Mistakes
Trying to set node.next to None instead of the previous node's next.
Not checking if the previous node exists.
3fill in blank
hard

Fix the error in the code to correctly handle deleting the last node when the list has only one node.

DSA Rust
fn delete_from_end(head: &mut Option<Box<Node>>) {
    if head.is_none() {
        return;
    }
    let mut current = head.as_mut();
    while let Some(node) = current {
        if node.next.is_none() {
            if node.prev.is_none() {
                [1];
            } else {
                node.prev.as_mut().map(|prev| prev.next = None);
            }
            break;
        }
        current = node.next.as_mut();
    }
}
Drag options to blanks, or click blank then click option'
Ahead = None
Bnode.next = None
Cnode.prev = None
Dhead.take()
Attempts:
3 left
💡 Hint
Common Mistakes
Trying to set head = None directly without take().
Not handling the single-node list case.
4fill in blank
hard

Fill both blanks to complete the function that deletes the last node and returns its value.

DSA Rust
fn delete_from_end(head: &mut Option<Box<Node>>) -> Option<i32> {
    if head.is_none() {
        return None;
    }
    let mut current = head.as_mut();
    while let Some(node) = current {
        if node.next.is_none() {
            let val = node.data;
            if node.prev.is_none() {
                [1];
            } else {
                node.prev.as_mut().map(|prev| prev.next = None);
            }
            return Some(val);
        }
        current = node.next.as_mut();
    }
    None
}
Drag options to blanks, or click blank then click option'
Ahead.take()
Bnode.prev = None
Cnode.next = None
Dhead = None
Attempts:
3 left
💡 Hint
Common Mistakes
Not returning the deleted node's value.
Forgetting to unlink the previous node's next pointer.
5fill in blank
hard

Fill all three blanks to implement a safe delete from end that updates pointers and returns the deleted value.

DSA Rust
fn delete_from_end(head: &mut Option<Box<Node>>) -> Option<i32> {
    if head.is_none() {
        return None;
    }
    let mut current = head.as_mut();
    while let Some(node) = current {
        if node.next.is_none() {
            let val = node.data;
            if node.prev.is_none() {
                [1];
            } else {
                node.prev.as_mut().map(|prev| prev.next = [2]);
            }
            [3]
        }
        current = node.next.as_mut();
    }
    None
}
Drag options to blanks, or click blank then click option'
Ahead.take()
BNone
Creturn Some(val)
Dnode.next
Attempts:
3 left
💡 Hint
Common Mistakes
Not returning the deleted value.
Incorrectly updating pointers causing dangling references.
Forgetting to handle the single-node list case.

Practice

(1/5)
1. What happens when you delete the last node from a doubly linked list that has multiple nodes?
easy
A. The second last node becomes the new tail and its next pointer is set to null
B. The head pointer is set to null
C. The list becomes circular
D. The first node is deleted instead

Solution

  1. Step 1: Understand the tail node removal

    When deleting the last node, the node before it becomes the new tail.
  2. Step 2: Update pointers

    The new tail's next pointer must be set to null to mark the end of the list.
  3. Final Answer:

    The second last node becomes the new tail and its next pointer is set to null -> Option A
  4. Quick Check:

    Tail update = new tail with next = null [OK]
Hint: Last node removal means update tail and set next to null [OK]
Common Mistakes:
  • Not updating the tail pointer
  • Forgetting to set next pointer of new tail to null
  • Deleting the head instead of the tail
2. Which Rust code snippet correctly deletes the last node from a doubly linked list?
easy
A. if let Some(tail) = self.tail.take() { if let Some(prev) = tail.prev.take() { prev.next = null; self.tail = Some(prev); } else { self.head = null; } }
B. self.head = null; self.tail = null;
C. self.tail = self.tail.unwrap().prev;
D. self.tail = null; self.head = null;

Solution

  1. Step 1: Check tail existence and update pointers

    The code safely takes the tail node, then updates the previous node's next pointer to null.
  2. Step 2: Update tail or head accordingly

    If previous node exists, tail is updated to it; else, list becomes empty by setting head to null.
  3. Final Answer:

    Code snippet that safely updates tail and head pointers -> Option A
  4. Quick Check:

    Safe pointer update with if let Some(tail) = self.tail.take() { if let Some(prev) = tail.prev.take() { prev.next = null; self.tail = Some(prev); } else { self.head = null; } } [OK]
Hint: Use take() and update prev.next and tail safely [OK]
Common Mistakes:
  • Directly assigning tail without checking Option
  • Not updating previous node's next pointer
  • Setting head to null without checking list length
3. Given the following Rust code for a doubly linked list deletion from end, what will be the printed list after deletion?
let mut list = DoublyLinkedList::new();
list.push_back(1);
list.push_back(2);
list.push_back(3);
list.delete_from_end();
list.print();
medium
A. 1 -> 2 -> 3 -> null
B. 1 -> 2 -> null
C. 2 -> 3 -> null
D. null

Solution

  1. Step 1: Initial list state

    The list contains nodes 1, 2, 3 in order.
  2. Step 2: Delete last node

    Deleting from end removes node 3, so list becomes 1 -> 2.
  3. Final Answer:

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

    After deletion, last node removed = 1 -> 2 [OK]
Hint: Deleting end removes last node only [OK]
Common Mistakes:
  • Assuming head node is deleted
  • Not updating tail pointer
  • Printing old list without deletion
4. Identify the bug in this Rust function that deletes the last node from a doubly linked list:
fn delete_from_end(&mut self) {
    if self.tail.is_none() {
        return;
    }
    let tail = self.tail.unwrap();
    if let Some(prev) = tail.prev {
        prev.next = null;
        self.tail = Some(prev);
    } else {
        self.head = null;
        self.tail = null;
    }
}
medium
A. prev.next is not set to null
B. Not updating head pointer when list has multiple nodes
C. Using unwrap() on Option without safe handling causes panic
D. Function does not check if list is empty

Solution

  1. Step 1: Analyze unwrap() usage

    Calling unwrap() on tail without checking can panic if tail is null.
  2. Step 2: Suggest safe handling

    Use if let or take() to safely handle Option values without panic.
  3. Final Answer:

    Using unwrap() on Option without safe handling causes panic -> Option C
  4. Quick Check:

    Unsafe unwrap() = panic risk [OK]
Hint: Avoid unwrap() on Option; use safe pattern matching [OK]
Common Mistakes:
  • Ignoring Option safety and causing runtime panic
  • Not updating tail pointer after deletion
  • Forgetting to set prev.next to null
5. You have a doubly linked list with nodes containing values [10, 20, 30]. After deleting the last node twice, what will be the state of the list?
hard
A. 10 -> 20 -> null
B. null
C. 20 -> 30 -> null
D. 10 -> null

Solution

  1. Step 1: Initial list nodes

    The list starts as 10 -> 20 -> 30.
  2. Step 2: Delete last node once

    Removing last node 30 results in 10 -> 20.
  3. Step 3: Delete last node again

    Removing last node 20 results in 10.
  4. Final Answer:

    10 -> null -> Option D
  5. Quick Check:

    Two deletions remove last two nodes [OK]
Hint: Each delete removes last node, update tail and next [OK]
Common Mistakes:
  • Deleting head instead of tail
  • Not updating tail after each deletion
  • Assuming list becomes empty too early
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