Bird
Raised Fist0
DSA Rustprogramming~5 mins

Insert at Beginning Head Insert in DSA Rust - Time & Space Complexity

Choose your learning style10 modes available
Time Complexity: Insert at Beginning Head Insert
O(1)
Understanding Time Complexity

We want to understand how long it takes to add a new item at the start of a linked list.

How does the time needed change as the list grows?

Scenario Under Consideration

Analyze the time complexity of the following code snippet.


struct Node {
    value: i32,
    next: Option>,
}

fn insert_at_head(head: &mut Option>, val: i32) {
    let new_node = Box::new(Node { value: val, next: head.take() });
    *head = Some(new_node);
}
    

This code adds a new node at the start of a singly linked list by adjusting the head pointer.

Identify Repeating Operations

Identify the loops, recursion, array traversals that repeat.

  • Primary operation: Creating a new node and updating the head pointer.
  • How many times: This happens once per insertion, no loops or traversals involved.
How Execution Grows With Input

Adding a node at the start takes the same steps no matter how big the list is.

Input Size (n)Approx. Operations
105 steps
1005 steps
10005 steps

Pattern observation: The number of steps stays constant as the list grows.

Final Time Complexity

Time Complexity: O(1)

This means adding at the start takes the same short time no matter how many items are in the list.

Common Mistake

[X] Wrong: "Adding at the start takes longer as the list grows because we must move all nodes."

[OK] Correct: We only change the head pointer and the new node's next link; no other nodes move or change.

Interview Connect

Knowing that head insertion is quick helps you choose the right method when speed matters in linked list operations.

Self-Check

"What if we changed to insert at the end of the list? How would the time complexity change?"

Practice

(1/5)
1. What does the "Insert at Beginning" operation do in a linked list?
easy
A. Adds a new node at the start of the list
B. Adds a new node at the end of the list
C. Deletes the first node of the list
D. Deletes the last node of the list

Solution

  1. Step 1: Understand the operation

    Inserting at the beginning means adding a new node before the current first node.
  2. Step 2: Effect on linked list

    The new node becomes the head, pushing existing nodes after it.
  3. Final Answer:

    Adds a new node at the start of the list -> Option A
  4. Quick Check:

    Insert at beginning = Add node at start [OK]
Hint: Insert at beginning means new head node [OK]
Common Mistakes:
  • Confusing insert at beginning with insert at end
  • Thinking it deletes nodes
  • Assuming it modifies middle nodes
2. Which of the following is the correct Rust syntax to insert a new node at the beginning of a singly linked list?
easy
A. self.head = Some(Box::new(Node { data, next: self.head.take() }));
B. self.head.push(Node { data, next: None });
C. self.head.append(Node { data, next: None });
D. self.head.insert(0, Node { data, next: None });

Solution

  1. Step 1: Understand Rust linked list insertion

    In Rust, to insert at head, create a new node with next pointing to current head, then update head.
  2. Step 2: Match syntax

    self.head = Some(Box::new(Node { data, next: self.head.take() })); uses Some(Box::new(Node { data, next: self.head.take() })) which correctly sets new node's next to old head.
  3. Final Answer:

    self.head = Some(Box::new(Node { data, next: self.head.take() })); -> Option A
  4. Quick Check:

    Rust head insert = new node points to old head [OK]
Hint: Use Some(Box::new(Node { data, next: old_head })) [OK]
Common Mistakes:
  • Using push or append on Option type
  • Not using Box::new for heap allocation
  • Forgetting to update head pointer
3. What will be the output linked list after executing this Rust code snippet?
let mut list = LinkedList::new();
list.insert_at_beginning(10);
list.insert_at_beginning(20);
list.insert_at_beginning(30);
list.print();
Assuming print() shows nodes from head to tail.
medium
A. null -> 10 -> 20 -> 30
B. 10 -> 20 -> 30 -> null
C. 30 -> 20 -> 10 -> null
D. 20 -> 30 -> 10 -> null

Solution

  1. Step 1: Trace insertions

    First insert 10 at beginning: list = 10 -> null Second insert 20 at beginning: list = 20 -> 10 -> null Third insert 30 at beginning: list = 30 -> 20 -> 10 -> null
  2. Step 2: Confirm print output

    Print shows from head to tail, so output is 30 -> 20 -> 10 -> null.
  3. Final Answer:

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

    Last inserted at head appears first [OK]
Hint: Last inserted at head appears first in list [OK]
Common Mistakes:
  • Assuming insertion adds at tail
  • Reading list backwards
  • Confusing print order
4. Identify the error in this Rust code for inserting at the beginning of a linked list:
fn insert_at_beginning(&mut self, data: i32) {
    let new_node = Box::new(Node { data, next: self.head });
    self.head = Some(new_node);
}
medium
A. data type i32 is incorrect for node data
B. self.head should be cloned before assigning to next
C. Box::new cannot be used here
D. self.head is an Option and needs to be taken with .take() to move ownership

Solution

  1. Step 1: Understand ownership rules

    self.head is an Option, so assigning it directly to next moves ownership, which is not allowed without .take().
  2. Step 2: Correct usage

    Using self.head.take() moves ownership out safely, allowing new_node.next to own old head.
  3. Final Answer:

    self.head is an Option and needs to be taken with .take() to move ownership -> Option D
  4. Quick Check:

    Use .take() to move Option ownership safely [OK]
Hint: Use .take() to move Option ownership when inserting [OK]
Common Mistakes:
  • Assigning Option without .take()
  • Ignoring Rust ownership rules
  • Using wrong data types
5. Given a Rust singly linked list, how would you modify the insert_at_beginning method to handle inserting into an empty list and a non-empty list correctly without cloning nodes?
hard
A. Check if self.head is None, then assign new node; else append at tail
B. Use self.head = Some(Box::new(Node { data, next: self.head.take() })) to move ownership safely
C. Clone the entire list before inserting the new node
D. Use unsafe pointers to bypass ownership rules

Solution

  1. Step 1: Handle empty and non-empty list uniformly

    Using self.head.take() moves the current head out safely whether it is None or Some(node).
  2. Step 2: Create new node with next as old head

    Assign new node as head with next pointing to old head, no cloning needed.
  3. Final Answer:

    Use self.head = Some(Box::new(Node { data, next: self.head.take() })) to move ownership safely -> Option B
  4. Quick Check:

    Use .take() for safe ownership transfer in insert [OK]
Hint: Use .take() to handle empty and non-empty head safely [OK]
Common Mistakes:
  • Appending at tail instead of head
  • Cloning nodes unnecessarily
  • Using unsafe code without need
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