Delete from End of Doubly Linked List in DSA C# - Time & Space Complexity
We want to understand how long it takes to remove the last item from a doubly linked list.
How does the time needed change as the list gets bigger?
Analyze the time complexity of the following code snippet.
public void DeleteFromEnd()
{
if (tail == null) return; // empty list
if (tail.Prev == null) // only one node
{
head = null;
tail = null;
return;
}
tail = tail.Prev;
tail.Next = null;
}
This code removes the last node from a doubly linked list by updating pointers.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Updating the tail pointer and its previous node's next pointer.
- How many times: This happens once per call, no loops or recursion involved.
Removing the last node always takes the same steps, no matter how big the list is.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 4 steps |
| 100 | 4 steps |
| 1000 | 4 steps |
Pattern observation: The number of steps stays the same as the list grows.
Time Complexity: O(1)
This means deleting from the end takes a constant amount of time regardless of list size.
[X] Wrong: "Deleting from the end takes longer as the list grows because we must traverse the list."
[OK] Correct: Because the list keeps a direct pointer to the last node (tail), no traversal is needed.
Knowing that deleting from the end of a doubly linked list is quick shows you understand how pointers help speed up operations.
"What if we did not keep a tail pointer? How would the time complexity change?"
Practice
Solution
Step 1: Identify the last node and its previous node
In a doubly linked list, the last node's previous node is the second last node.Step 2: Update the second last node's next pointer
Set the second last node's next pointer to null to remove the last node from the list.Final Answer:
The second last node becomes the new tail and its next pointer is set to null. -> Option DQuick Check:
Deleting last node updates tail's next to null [OK]
- Setting head to null instead of updating tail
- Not updating the previous node's next pointer
- Deleting the first node by mistake
dll?Solution
Step 1: Move tail pointer to previous node
Setdll.Tailtodll.Tail.Previousto remove the last node.Step 2: Set new tail's next pointer to null
Updatedll.Tail.Nextto null to mark the end of the list.Final Answer:
dll.Tail = dll.Tail.Previous; dll.Tail.Next = null; -> Option BQuick Check:
Correct tail update syntax = dll.Tail = dll.Tail.Previous; dll.Tail.Next = null; [OK]
- Updating head instead of tail
- Not setting tail's next to null
- Setting both head and tail to null unnecessarily
dll.AddLast(1); dll.AddLast(2); dll.AddLast(3); dll.DeleteFromEnd(); dll.PrintList();
Solution
Step 1: Add nodes 1, 2, 3 to the list
The list becomes 1 -> 2 -> 3 -> null.Step 2: Delete the last node (3)
After deletion, the list becomes 1 -> 2 -> null.Final Answer:
1 -> 2 -> null -> Option CQuick Check:
Last node removed, list ends at 2 [OK]
- Assuming list remains unchanged
- Deleting head instead of tail
- Printing list before deletion
if (dll.Tail != null) { dll.Tail = dll.Tail.Previous; dll.Tail.Next = null; }Solution
Step 1: Check deletion when only one node exists
If only one node exists,dll.Tail.Previousis null, sodll.Tailbecomes null.Step 2: Accessing
After settingdll.Tail.Nextcauses errordll.Tailto null, accessingdll.Tail.Nextthrows NullReferenceException.Final Answer:
NullReferenceException when list has only one node -> Option AQuick Check:
Accessing property on null tail causes error [OK]
- Not handling single-node list case
- Ignoring null checks before pointer access
- Assuming head updates automatically
Solution
Step 1: Initial list and first deletion
List is 10 <-> 20 <-> 30 <-> 40. Deleting last node removes 40, list becomes 10 <-> 20 <-> 30.Step 2: Second deletion removes 30
After second deletion, list becomes 10 <-> 20, and tail points to node with value 20.Final Answer:
10 <-> 20 -> null, Tail = 20 -> Option AQuick Check:
Two deletions remove last two nodes [OK]
- Deleting only one node instead of two
- Not updating tail after deletions
- Confusing head and tail pointers
Ready to prove it?
Pass the test and this pattern moves unknown
