📖 Scenario: You are building a simple playlist manager. Each song is a node in a doubly linked list. You want to add new songs to the end of the playlist.
🎯 Goal: Create a doubly linked list and write code to insert a new node at the end. Finally, print the playlist from start to end.
📋 What You'll Learn
Define a struct Node with data, prev, and next fields
Create a struct DoublyLinkedList with head and tail pointers
Implement a method insert_at_end to add a new node at the end
Print the list from head to tail showing all node data
💡 Why This Matters
🌍 Real World
Doubly linked lists are used in music players, undo-redo features, and navigation history where you need to move forward and backward easily.
💼 Career
Understanding linked lists is fundamental for software engineers working on data structures, memory management, and performance optimization.
Progress0 / 4 steps
1
Create the Node and DoublyLinkedList structs
Define a struct called Node with a field data of type i32, and two Option<Box<Node>> fields called prev and next. Then define a struct called DoublyLinkedList with two fields: head and tail, both of type Option<Box<Node>>.
DSA Rust
Hint
Use Option<Box<Node>> for prev and next to allow null pointers.
2
Add a new method insert_at_end to DoublyLinkedList
Inside DoublyLinkedList, add a method called insert_at_end that takes &mut self and a parameter data of type i32. This method will add a new node with the given data at the end of the list.
DSA Rust
Hint
Use self.tail.take() to get the current tail, then update pointers to add the new node at the end.
3
Initialize an empty DoublyLinkedList and insert nodes
Create a mutable variable called list of type DoublyLinkedList with head and tail set to None. Then call insert_at_end on list to insert nodes with data 10, 20, and 30.
DSA Rust
Hint
Initialize list with head and tail as None. Then call insert_at_end three times with the given values.
4
Print the list from head to tail
Add code inside main to print the data of each node from head to tail in the format: 10 -> 20 -> 30 -> None. Use a variable current to traverse the list starting from list.head.as_ref().
DSA Rust
Hint
Use a while let Some(node) = current loop to traverse and print each node's data followed by ->. End with None.
Practice
(1/5)
1. What is the main purpose of inserting a node at the end of a doubly linked list?
easy
A. To reverse the list
B. To remove the first node
C. To add a new element after the last node
D. To find the middle node
Solution
Step 1: Understand the structure of a doubly linked list
A doubly linked list has nodes connected forward and backward, allowing traversal in both directions.
Step 2: Purpose of insertion at the end
Inserting at the end means adding a new node after the current last node, updating pointers accordingly.
Final Answer:
To add a new element after the last node -> Option C
Quick Check:
Insert at end = add after last node [OK]
Hint: Insert at end means add after last node [OK]
Common Mistakes:
Confusing insertion at end with deletion
Thinking insertion reverses the list
Assuming insertion happens at the start
2. Which Rust code snippet correctly creates a new node and inserts it at the end of a doubly linked list?
easy
A. let new_node = Node::new(value); new_node.prev = Some(head); head.next = Some(new_node);
B. let new_node = Node::new(value); head.prev = Some(new_node); new_node.next = Some(head);
C. let new_node = Node::new(value); new_node.next = Some(tail); tail.prev = Some(new_node);
D. let new_node = Node::new(value); tail.next = Some(new_node); new_node.prev = Some(tail);
Solution
Step 1: Create new node with given value
Use Node::new(value) to create a new node.
Step 2: Link new node after tail
Set tail.next to new_node and new_node.prev to tail to insert at end.
Final Answer:
let new_node = Node::new(value); tail.next = Some(new_node); new_node.prev = Some(tail); -> Option D
Quick Check:
New node after tail = let new_node = Node::new(value); tail.next = Some(new_node); new_node.prev = Some(tail); [OK]
Hint: New node's prev points to tail; tail's next points to new node [OK]
Common Mistakes:
Linking new node before head instead of after tail
Swapping next and prev pointers incorrectly
Not updating tail's next pointer
3. Given the Rust code below, what will be the printed list after inserting 4 at the end?
struct Node {
value: i32,
prev: Option,
next: Option,
}
// Assume list initially: 1 <-> 2 <-> 3
// Insert 4 at end
// Print list from head to tail
medium
A. 1 <-> 2 <-> 3 <-> 4 <-> null
B. 4 <-> 1 <-> 2 <-> 3 <-> null
C. 1 <-> 2 <-> 4 <-> 3 <-> null
D. 1 <-> 2 <-> 3 <-> null
Solution
Step 1: Understand initial list structure
The list is 1 linked to 2, linked to 3, with 3 as tail.
Step 2: Insert 4 at the end
Adding 4 after 3 updates 3.next to 4 and 4.prev to 3.
Final Answer:
1 <-> 2 <-> 3 <-> 4 <-> null -> Option A
Quick Check:
Insert at end adds 4 after 3 [OK]
Hint: New node appears after last node in printed list [OK]
Common Mistakes:
Inserting new node at start instead of end
Not updating next pointer of last node
Printing list without new node
4. Identify the error in this Rust code snippet for inserting at the end of a doubly linked list:
A. tail is not updated correctly; should update tail's next pointer
B. new_node.prev should be None for end insertion
C. new_node should not be boxed
D. value should be mutable
Solution
Step 1: Check pointer updates
tail is reassigned locally, but tail's next pointer is not updated to link new_node.
Step 2: Correct linking needed
Must set tail's next to new_node and new_node.prev to tail, then update tail reference.
Final Answer:
tail is not updated correctly; should update tail's next pointer -> Option A
Quick Check:
Update tail.next to new_node [OK]
Hint: Always update tail's next pointer when inserting at end [OK]
Common Mistakes:
Only reassigning tail without linking nodes
Setting prev pointer incorrectly
Ignoring ownership rules in Rust
5. You have a doubly linked list with nodes: 10 <-> 20 <-> 30. You want to insert 25 at the end but also keep a pointer to the middle node for quick access. After insertion, which node should the middle pointer reference to keep it as the middle of the list?
hard
A. 25
B. 20
C. 30
D. 10
Solution
Step 1: Understand list before insertion
List is 10 <-> 20 <-> 30; middle is 20 (second of three nodes).
Step 2: Insert 25 at end and find new middle
List becomes 10 <-> 20 <-> 30 <-> 25. With 4 nodes, middle is between 20 and 30, usually the second node (20) to keep balance.
Final Answer:
20 -> Option B
Quick Check:
Middle of 4 nodes = 2nd node [OK]
Hint: Middle of even nodes is lower middle [OK]
Common Mistakes:
Moving middle pointer to last inserted node
Choosing last node as middle
Not updating middle pointer after insertion
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.