Sort a Linked List Using Merge Sort in DSA Java - Time & Space Complexity
We want to understand how long it takes to sort a linked list using merge sort as the list grows.
How does the sorting time change when the list gets bigger?
Analyze the time complexity of the following code snippet.
public ListNode mergeSort(ListNode head) {
if (head == null || head.next == null) return head;
ListNode mid = getMiddle(head);
ListNode rightHead = mid.next;
mid.next = null;
ListNode left = mergeSort(head);
ListNode right = mergeSort(rightHead);
return merge(left, right);
}
This code splits the linked list into halves, sorts each half recursively, and then merges the sorted halves.
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 happens n times in total.
Each split divides the list into two smaller parts, and merging combines them back.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 40 operations |
| 100 | About 700 operations |
| 1000 | About 10,000 operations |
Pattern observation: The operations grow a bit faster than n but much slower than n squared, roughly n times log n.
Time Complexity: O(n log n)
This means the time to sort grows a little more than linearly as the list gets bigger, but still efficient for large lists.
[X] Wrong: "Merge sort on linked list is as slow as bubble sort, so it takes n squared time."
[OK] Correct: Merge sort splits the list and merges in a way that only needs about n log n steps, much faster than n squared.
Understanding merge sort on linked lists shows you can handle recursion and pointers well, skills useful in many coding problems.
"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, so algorithms needing it perform poorly.Step 2: Compare merge sort and quicksort
Merge sort splits and merges lists using pointers, avoiding random access, making it efficient for linked lists.Final Answer:
Merge sort does not require random access and works well with linked lists. -> Option CQuick Check:
Merge sort suits linked lists better than quicksort [OK]
- Thinking quicksort is always faster on linked lists
- Assuming arrays and linked lists behave the same
- Ignoring random access needs
Solution
Step 1: Identify base case for recursion
When the list is empty or has one node, it is already sorted.Step 2: Check condition correctness
Condition 'head == null || head.next == null' correctly checks for empty or single-node list.Final Answer:
if (head == null || head.next == null) return head; -> Option BQuick Check:
Base case returns head if list size ⤠1 [OK]
- Using && instead of || in base case
- Returning null incorrectly for single node
- Not handling empty list properly
Solution
Step 1: Split the list into halves
Split into (4 -> 2) and (1 -> 3).Step 2: Recursively sort halves and merge
Sort (4 -> 2) to (2 -> 4), sort (1 -> 3) to (1 -> 3), then merge to (1 -> 2 -> 3 -> 4).Final Answer:
1 -> 2 -> 3 -> 4 -> null -> Option AQuick Check:
Sorted list ascending order [OK]
- Not splitting list correctly
- Merging without sorting halves
- Mixing node order during merge
Node merge(Node a, Node b) {
if (a == null) return b;
if (b == null) return a;
if (a.data < b.data) {
a.next = merge(a.next, b);
return b;
} else {
b.next = merge(a, b.next);
return a;
}
}Solution
Step 1: Analyze return statements
When a.data < b.data, function should return 'a' but returns 'b' incorrectly.Step 2: Correct return node after recursion
Return the node chosen as smaller to maintain sorted order; here it should be 'a' or 'b' accordingly.Final Answer:
The function returns the wrong node after recursion. -> Option DQuick Check:
Return chosen smaller node to merge correctly [OK]
- Returning wrong node after recursive call
- Ignoring base cases
- Incorrect comparison operator
Solution
Step 1: Sort the list using merge sort
Sorted order is 2 -> 3 -> 5 -> 7 -> 8 -> null after splitting and merging.Step 2: Explain merge sort advantage
Merge sort is O(n log n) and uses pointers efficiently; bubble sort is O(n²) and inefficient for linked lists.Final Answer:
2 -> 3 -> 5 -> 7 -> 8 -> null; Merge sort is faster and uses less memory on linked lists. -> Option AQuick Check:
Sorted list + merge sort efficiency [OK]
- Confusing bubble sort as faster
- Incorrect sorted order
- Thinking merge sort can't handle linked lists
Ready to prove it?
Pass the test and this pattern moves unknown
