Sort a Linked List Using Merge Sort in DSA C - Time & Space Complexity
We want to understand how the time needed to sort a linked list grows as the list gets bigger.
Specifically, we ask: How does merge sort handle linked lists in terms of speed?
Analyze the time complexity of the following code snippet.
// Merge sort for linked list
Node* mergeSort(Node* head) {
if (!head || !head->next) return head;
Node* mid = getMiddle(head);
Node* left = head;
Node* right = mid->next;
mid->next = NULL;
left = mergeSort(left);
right = mergeSort(right);
return merge(left, right);
}
This code splits the list into halves, sorts each half recursively, and merges them back.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursively splitting the list and merging sorted halves.
- How many times: The list is split about log n times, and merging touches all nodes each time.
Each split divides the list in half, and merging processes all nodes once per level.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 * 4 = 40 |
| 100 | About 100 * 7 = 700 |
| 1000 | About 1000 * 10 = 10,000 |
Pattern observation: Operations grow roughly as n times log n, meaning doubling input size increases work a bit more than double.
Time Complexity: O(n log n)
This means sorting takes longer as the list grows, but the increase is controlled and efficient for large lists.
[X] Wrong: "Merge sort on linked list is as slow as bubble sort, so it's O(n²)."
[OK] Correct: Merge sort splits the list and merges efficiently, avoiding repeated comparisons like bubble sort, so it runs much faster.
Understanding merge sort on linked lists shows you can handle recursion and pointers well, skills that are useful in many coding challenges.
"What if we used quicksort instead of merge sort on the linked list? How would the time complexity change?"
Practice
Solution
Step 1: Understand linked list access
Linked lists do not support fast random access, unlike arrays.Step 2: Compare sorting algorithms
Merge sort works well with sequential access, while quicksort relies on random access for efficiency.Final Answer:
Merge sort does not require random access, which suits linked lists well. -> Option AQuick Check:
Linked list + merge sort = no random access needed [OK]
- Thinking quicksort is always better
- Assuming merge sort needs random access
- Confusing stability of sorting algorithms
Solution
Step 1: Identify splitting technique
The fast and slow pointer method finds the middle node efficiently.Step 2: Understand pointer movement
Slow pointer moves one node at a time, fast pointer moves two nodes; when fast reaches end, slow is at mid.Final Answer:
Use two pointers: slow moves 1 step, fast moves 2 steps; slow marks mid. -> Option BQuick Check:
Fast/slow pointers split linked list [OK]
- Trying to split by node values
- Using only one pointer to split
- Not stopping fast pointer correctly
Solution
Step 1: Break list into halves recursively
Split into (4 -> 2) and (1 -> 3), then further split until single nodes.Step 2: Merge sorted halves
Merge nodes in order: 1, 2, 3, 4 to get sorted list.Final Answer:
1 -> 2 -> 3 -> 4 -> NULL -> Option DQuick Check:
Sorted ascending order = 1,2,3,4 [OK]
- Confusing merge order
- Not splitting correctly
- Assuming original order remains
Node* mergeSort(Node* head) {
if (!head || !head->next) return head;
Node* slow = head;
Node* fast = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
}
Node* mid = slow->next;
slow->next = NULL;
Node* left = mergeSort(head);
Node* right = mergeSort(mid);
return merge(left, right);
}Solution
Step 1: Analyze pointer initialization
Fast pointer should start at head->next to correctly find middle for even nodes.Step 2: Understand pointer movement impact
Starting fast at head skips the first node, causing incorrect mid calculation.Final Answer:
Fast pointer should start at head->next, not head. -> Option CQuick Check:
Fast pointer start affects mid node [OK]
- Starting fast at head
- Moving slow pointer incorrectly
- Ignoring base case conditions
Solution
Step 1: Understand merge sort stability
Merge sort preserves order of equal elements, so duplicates stay in relative order.Step 2: Sort values ascending
Sorted order is 2, 3, 5, 5, 8 with duplicates adjacent.Final Answer:
2 -> 3 -> 5 -> 5 -> 8 -> NULL -> Option AQuick Check:
Sorted with duplicates preserved = 2,3,5,5,8 [OK]
- Assuming duplicates get removed
- Sorting duplicates incorrectly
- Mixing order of duplicates
Ready to prove it?
Pass the test and this pattern moves unknown
