Challenge - 5 Problems
Traversal Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediateOutput of Forward Traversal in Doubly Linked List
What is the printed output of the doubly linked list after inserting nodes 1, 2, and 3 and traversing forward?
DSA Rust
struct Node {
data: i32,
next: Option<Box<Node>>,
prev: Option<*mut Node>,
}
struct DoublyLinkedList {
head: Option<Box<Node>>,
tail: Option<*mut Node>,
}
impl DoublyLinkedList {
fn new() -> Self {
DoublyLinkedList { head: None, tail: None }
}
fn append(&mut self, data: i32) {
let mut new_node = Box::new(Node { data, next: None, prev: None });
let raw_new: *mut _ = &mut *new_node;
match self.tail {
None => {
self.head = Some(new_node);
self.tail = Some(raw_new);
}
Some(tail) => unsafe {
(*tail).next = Some(new_node);
(*raw_new).prev = Some(tail);
self.tail = Some(raw_new);
},
}
}
fn traverse_forward(&self) {
let mut current = self.head.as_ref();
while let Some(node) = current {
print!("{} -> ", node.data);
current = node.next.as_ref();
}
print!("null");
}
}
fn main() {
let mut list = DoublyLinkedList::new();
list.append(1);
list.append(2);
list.append(3);
list.traverse_forward();
}Attempts:
2 left
💡 Hint
Think about how nodes are appended and how traversal moves from head to tail.
✗ Incorrect
The append method adds nodes at the end. Traversing forward starts at head and moves through next pointers, printing 1, then 2, then 3, then null.
❓ Predict Output
intermediateOutput of Backward Traversal in Doubly Linked List
What is the printed output of the doubly linked list after inserting nodes 1, 2, and 3 and traversing backward?
DSA Rust
struct Node {
data: i32,
next: Option<Box<Node>>,
prev: Option<*mut Node>,
}
struct DoublyLinkedList {
head: Option<Box<Node>>,
tail: Option<*mut Node>,
}
impl DoublyLinkedList {
fn new() -> Self {
DoublyLinkedList { head: None, tail: None }
}
fn append(&mut self, data: i32) {
let mut new_node = Box::new(Node { data, next: None, prev: None });
let raw_new: *mut _ = &mut *new_node;
match self.tail {
None => {
self.head = Some(new_node);
self.tail = Some(raw_new);
}
Some(tail) => unsafe {
(*tail).next = Some(new_node);
(*raw_new).prev = Some(tail);
self.tail = Some(raw_new);
},
}
}
fn traverse_backward(&self) {
let mut current = self.tail;
while let Some(node_ptr) = current {
unsafe {
print!("{} -> ", (*node_ptr).data);
current = (*node_ptr).prev;
}
}
print!("null");
}
}
fn main() {
let mut list = DoublyLinkedList::new();
list.append(1);
list.append(2);
list.append(3);
list.traverse_backward();
}Attempts:
2 left
💡 Hint
Backward traversal starts from tail and moves through prev pointers.
✗ Incorrect
The backward traversal prints nodes starting from tail (3), then 2, then 1, then null.
🔧 Debug
advancedIdentify the Error in Backward Traversal
What error will this Rust code produce when trying to traverse backward in a doubly linked list?
DSA Rust
fn traverse_backward(&self) {
let mut current = self.tail;
while let Some(node_ptr) = current {
print!("{} -> ", (*node_ptr).data);
current = (*node_ptr).prev.unwrap();
}
print!("null");
}Attempts:
2 left
💡 Hint
Dereferencing raw pointers in Rust requires a special block.
✗ Incorrect
Dereferencing raw pointers (*node_ptr) must be inside an unsafe block. Missing unsafe causes a compile-time error.
❓ Predict Output
advancedOutput After Mixed Forward and Backward Traversal
Given the doubly linked list with nodes 10, 20, 30 appended, what is the output of traversing forward then backward?
DSA Rust
struct Node {
data: i32,
next: Option<Box<Node>>,
prev: Option<*mut Node>,
}
struct DoublyLinkedList {
head: Option<Box<Node>>,
tail: Option<*mut Node>,
}
impl DoublyLinkedList {
fn new() -> Self {
DoublyLinkedList { head: None, tail: None }
}
fn append(&mut self, data: i32) {
let mut new_node = Box::new(Node { data, next: None, prev: None });
let raw_new: *mut _ = &mut *new_node;
match self.tail {
None => {
self.head = Some(new_node);
self.tail = Some(raw_new);
}
Some(tail) => unsafe {
(*tail).next = Some(new_node);
(*raw_new).prev = Some(tail);
self.tail = Some(raw_new);
},
}
}
fn traverse_forward(&self) {
let mut current = self.head.as_ref();
while let Some(node) = current {
print!("{} -> ", node.data);
current = node.next.as_ref();
}
}
fn traverse_backward(&self) {
let mut current = self.tail;
while let Some(node_ptr) = current {
unsafe {
print!("{} -> ", (*node_ptr).data);
current = (*node_ptr).prev;
}
}
}
}
fn main() {
let mut list = DoublyLinkedList::new();
list.append(10);
list.append(20);
list.append(30);
list.traverse_forward();
print!("null -> ");
list.traverse_backward();
print!("null");
}Attempts:
2 left
💡 Hint
Forward traversal prints from head to tail, backward from tail to head.
✗ Incorrect
First prints 10, 20, 30, then null, then backward prints 30, 20, 10, then null.
🧠 Conceptual
expertWhy Use Raw Pointers for Prev in Rust Doubly Linked List?
In Rust, why is the 'prev' pointer in a doubly linked list often declared as a raw pointer (*mut Node) instead of a Box or Option>?
Attempts:
2 left
💡 Hint
Think about Rust's ownership rules and how backward links can cause multiple owners.
✗ Incorrect
Rust's ownership rules prevent multiple owners of the same data. Using Box for prev would cause ownership conflicts. Raw pointers allow mutable aliasing without ownership, but require unsafe code.
