Heap Sort Algorithm in DSA Java - Time & Space Complexity
We want to understand how the time to sort a list using Heap Sort changes as the list grows.
How does the number of steps grow when the input size increases?
Analyze the time complexity of the following code snippet.
public void heapSort(int[] arr) {
int n = arr.length;
for (int i = n / 2 - 1; i >= 0; i--) {
heapify(arr, n, i);
}
for (int i = n - 1; i > 0; i--) {
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
heapify(arr, i, 0);
}
}
private void heapify(int[] arr, int n, int i) {
int largest = i;
int left = 2 * i + 1;
int right = 2 * i + 2;
if (left < n && arr[left] > arr[largest]) largest = left;
if (right < n && arr[right] > arr[largest]) largest = right;
if (largest != i) {
int swap = arr[i];
arr[i] = arr[largest];
arr[largest] = swap;
heapify(arr, n, largest);
}
}
This code builds a max heap from the array, then repeatedly extracts the largest element to sort the array.
- Primary operation: The heapify function which rearranges elements to maintain the heap property.
- How many times: Heapify is called once for each non-leaf node during building the heap (about n/2 times), and then called for each element removed from the heap (n-1 times), each call may recurse down the tree.
As the input size grows, the number of heapify operations grows roughly proportional to n times the height of the heap, which grows slowly with n.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 30 to 40 heapify steps |
| 100 | About 700 to 800 heapify steps |
| 1000 | About 10,000 heapify steps |
Pattern observation: The operations grow a bit faster than linearly but much slower than quadratically, roughly n times log n.
Time Complexity: O(n log n)
This means the time to sort grows a little more than linearly, multiplying the input size by the height of the heap.
[X] Wrong: "Heap Sort is as slow as bubble sort because it uses loops inside loops."
[OK] Correct: Heap Sort uses a smart tree structure that limits how far elements move, so it runs much faster than simple nested loops.
Understanding Heap Sort's time complexity shows you can analyze efficient sorting methods, a key skill for many coding challenges and real-world tasks.
"What if we used a min heap instead of a max heap? How would the time complexity change?"
Practice
Solution
Step 1: Understand heap property
A heap is a special tree-based structure where the parent node is either greater (max-heap) or smaller (min-heap) than its children.Step 2: Role in Heap Sort
Heap Sort uses a max-heap to quickly find the largest element at the root, then removes it to build the sorted array.Final Answer:
To efficiently find and remove the largest (or smallest) element -> Option CQuick Check:
Heap = fast max/min retrieval [OK]
- Thinking heap stores sorted elements permanently
- Confusing heap with a simple array
- Assuming heap counts elements
Solution
Step 1: Identify heapify starting point
Heapify must start from the last non-leaf node, which is at index n/2 - 1, moving upwards.Step 2: Loop direction and range
The loop runs backwards from n/2 - 1 down to 0 to ensure all subtrees satisfy heap property.Final Answer:
for (int i = n / 2 - 1; i >= 0; i--) heapify(arr, i, n); -> Option BQuick Check:
Build heap from last non-leaf node [OK]
- Starting heapify from 0 upwards
- Heapifying leaf nodes unnecessarily
- Looping in wrong direction
[4, 10, 3, 5, 1]?Solution
Step 1: Build max heap from array
Max heap of [4,10,3,5,1] is [10,5,3,4,1].Step 2: Extract max and heapify repeatedly
Remove 10, heapify remaining; then 5, then 4, then 3, then 1, resulting in sorted array [1,3,4,5,10].Final Answer:
[1, 3, 4, 5, 10] -> Option AQuick Check:
Heap Sort sorts ascending [OK]
- Confusing max heap array with sorted array
- Forgetting to heapify after extraction
- Assuming heap sort outputs descending by default
void heapify(int[] arr, int i, int n) {
int largest = i;
int left = 2 * i + 1;
int right = 2 * i + 2;
if (left < n && arr[left] < arr[largest]) largest = left;
if (right < n && arr[right] > arr[largest]) largest = right;
if (largest != i) {
int temp = arr[i]; arr[i] = arr[largest]; arr[largest] = temp;
heapify(arr, largest, n);
}
}Solution
Step 1: Check comparison operators for max heap
For max heap, parent should be greater than children, so we check if child > parent to update largest.Step 2: Identify incorrect comparison
The code uses 'arr[left] < arr[largest]' which is wrong; it should be 'arr[left] > arr[largest]'.Final Answer:
The comparison for left child should be '>' instead of '<' -> Option DQuick Check:
Max heap needs '>' comparison [OK]
- Using '<' instead of '>' for max heap
- Wrong recursive call index
- Incorrect child index calculation
Solution
Step 1: Understand duplicates in Heap Sort
Heap Sort treats duplicates like any other elements; duplicates do not affect the heap property or sorting steps.Step 2: Time complexity with duplicates
Heap Sort always runs in O(n log n) time in worst case, regardless of duplicates.Final Answer:
Heap Sort handles duplicates normally with O(n log n) worst-case time -> Option AQuick Check:
Duplicates do not affect Heap Sort time [OK]
- Thinking duplicates cause slower sorting
- Assuming Heap Sort needs extra space for duplicates
- Confusing Heap Sort with unstable sorts
Ready to prove it?
Pass the test and this pattern moves unknown
