Insert at Beginning of Circular Linked List in DSA C++ - Time & Space Complexity
We want to understand how the time to insert a new node at the start of a circular linked list changes as the list grows.
How does the number of steps needed grow when the list gets bigger?
Analyze the time complexity of the following code snippet.
struct Node {
int data;
Node* next;
};
void insertAtBeginning(Node*& tail, int value) {
Node* newNode = new Node{value, nullptr};
if (!tail) {
newNode->next = newNode;
tail = newNode;
} else {
newNode->next = tail->next;
tail->next = newNode;
}
}
This code inserts a new node at the start of a circular linked list by adjusting pointers.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Pointer updates to insert the new node.
- How many times: These pointer changes happen only once per insertion, no loops or recursion.
Since the insertion only changes a few pointers, the number of steps stays the same no matter how big the list is.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 3-4 pointer changes |
| 100 | 3-4 pointer changes |
| 1000 | 3-4 pointer changes |
Pattern observation: The work stays constant regardless of list size.
Time Complexity: O(1)
This means the insertion takes the same amount of time no matter how many nodes are in the list.
[X] Wrong: "Inserting at the beginning requires going through the whole list to find the start."
[OK] Correct: Because we keep a pointer to the tail, we can access the start directly without walking through the list.
Knowing this operation is constant time shows you understand how circular linked lists use pointers smartly to avoid extra work.
"What if we did not keep a tail pointer and only had a head pointer? How would the time complexity change?"
Practice
Solution
Step 1: Understand the circular linked list structure
In a circular linked list, the last node points back to the head node, forming a circle.Step 2: Insert new node at beginning
The new node is linked to the current head, and the last node's next pointer is updated to this new node, making it the new head.Final Answer:
The new node becomes the head and points to the old head, maintaining the circular link. -> Option CQuick Check:
New head points to old head, circle intact = A [OK]
- Forgetting to update last node's next pointer
- Breaking the circular link by not linking last node
- Replacing last node instead of adding new head
Solution
Step 1: Create new node dynamically
Use 'new' keyword to allocate memory for new node: Node* newNode = new Node(data);Step 2: Link new node and update pointers
Set newNode->next to current head, update last node's next to newNode, then update head to newNode.Final Answer:
Node* newNode = new Node(data); newNode->next = head; last->next = newNode; head = newNode; -> Option AQuick Check:
Dynamic node + last->next update + head change = C [OK]
- Not updating last node's next pointer
- Using stack allocation for node causing scope issues
- Assigning head before updating last->next
struct Node {
int data;
Node* next;
};
Node* head = new Node{20, nullptr};
head->next = head;
// Insert 10 at beginning
Node* newNode = new Node{10, nullptr};
Node* temp = head;
while(temp->next != head) {
temp = temp->next;
}
newNode->next = head;
temp->next = newNode;
head = newNode;
// Print list
Node* curr = head;
do {
std::cout << curr->data << " -> ";
curr = curr->next;
} while(curr != head);
std::cout << "null";
Solution
Step 1: Initial list and insertion
Initially, list has one node with data 20 pointing to itself. New node 10 is inserted before 20, updating last node's next to new node and head to new node.Step 2: Print traversal
Traversal starts at head (10), prints 10, moves to 20, prints 20, then back to head stops loop.Final Answer:
10 -> 20 -> null -> Option DQuick Check:
New head 10 followed by 20 = A [OK]
- Not updating last node's next pointer
- Printing stops too early or infinite loop
- Confusing order of nodes after insertion
void insertAtBeginning(Node*& head, int data) {
Node* newNode = new Node{data, nullptr};
newNode->next = head;
head = newNode;
Node* temp = head;
while(temp->next != head) {
temp = temp->next;
}
temp->next = head;
}Solution
Step 1: Analyze pointer updates order
The code updates head to newNode before finding the last node, so temp starts at newNode, causing the while loop to never find the last node correctly.Step 2: Consequence of wrong order
Because last node is not found properly, temp->next = head may not update the correct node, breaking the circular link or causing infinite loops.Final Answer:
The last node's next pointer is updated after changing head, causing infinite loop. -> Option AQuick Check:
Update last node before changing head to avoid loop [OK]
- Changing head before updating last node's next
- Not handling empty list case
- Incorrect while loop condition
Solution
Step 1: Create new node and find last node
Create new node with data 1. Traverse list to find last node (node pointing back to head).Step 2: Update pointers in correct order
Set last->next to newNode, newNode->next to head, then update head to newNode to maintain circular link.Final Answer:
Create new node with data 1; find last node; set last->next = newNode; set newNode->next = head; update head = newNode; -> Option BQuick Check:
Last node updated before head change = B [OK]
- Changing head before updating last node's next
- Setting newNode->next to nullptr breaks circular link
- Incorrect order of pointer updates
Ready to prove it?
Pass the test and this pattern moves unknown
