Build Heap from Array Heapify in DSA Typescript - Time & Space Complexity
We want to understand how long it takes to build a heap from an array using heapify.
Specifically, how the time grows as the array size increases.
Analyze the time complexity of the following code snippet.
function buildHeap(arr: number[]): void {
const n = arr.length;
for (let i = Math.floor(n / 2) - 1; i >= 0; i--) {
heapify(arr, n, i);
}
}
function heapify(arr: number[], n: number, i: number): void {
let largest = i;
const left = 2 * i + 1;
const 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) {
[arr[i], arr[largest]] = [arr[largest], arr[i]];
heapify(arr, n, largest);
}
}
This code builds a max heap from an unsorted array by calling heapify from the bottom up.
- Primary operation: The heapify function called on each non-leaf node.
- How many times: Called once for each node from the middle to the root, about n/2 times.
- Inside heapify: It may recurse down the tree, moving elements to maintain heap property.
Heapify runs faster on nodes near the bottom because they have fewer levels to move down.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 20 operations |
| 100 | About 300 operations |
| 1000 | About 4000 operations |
Pattern observation: The total work grows roughly linearly with input size, not quadratically.
Time Complexity: O(n)
This means building a heap from an array takes time proportional to the number of elements.
[X] Wrong: "Heapify runs in O(n log n) because heapify is called n/2 times and each call takes O(log n)."
[OK] Correct: Most heapify calls run on nodes near the bottom with small heights, so they take less time. The total adds up to O(n), not O(n log n).
Understanding this helps you explain why heap construction is efficient and shows you can analyze recursive code carefully.
What if we called heapify starting from the root down to the last node instead of bottom-up? How would the time complexity change?
Practice
heapify process when building a heap from an array?Solution
Step 1: Understand heap property
A heap is a special tree where parent nodes follow a specific order compared to children (max-heap or min-heap).Step 2: Role of heapify
Heapify rearranges elements so that the heap property holds for every subtree, starting from the bottom.Final Answer:
To rearrange the array elements to satisfy the heap property -> Option DQuick Check:
Heapify = Rearrange for heap property [OK]
- Thinking heapify sorts the array
- Confusing heapify with finding max element
- Assuming heapify reverses the array
arr of length n?Solution
Step 1: Identify last non-leaf node index
In a heap array, last non-leaf node is at index Math.floor(n/2) - 1.Step 2: Loop from last non-leaf to root
We heapify from this index down to 0 to ensure all subtrees satisfy heap property.Final Answer:
for(let i = Math.floor(n / 2) - 1; i >= 0; i--) { heapify(arr, n, i); } -> Option BQuick Check:
Start heapify at last non-leaf node [OK]
- Starting heapify from 0 upwards
- Starting heapify from last element
- Looping beyond last non-leaf node
arr = [3, 9, 2, 1, 4, 5], what is the array after building a max-heap using heapify?Solution
Step 1: Start heapify from index 2 (Math.floor(6/2)-1)
Heapify at index 2: children 5 (index 5), swap 2 and 5 to get [3,9,5,1,4,2].Step 2: Heapify at index 1 and 0
Index 1: children 1 and 4, max is 9 at index 1, no swap. Index 0: children 9 and 5, swap 3 and 9. Final array: [9,4,5,1,3,2]Final Answer:
[9, 4, 5, 1, 3, 2] -> Option AQuick Check:
Max-heap root is 9, children smaller [OK]
- Not swapping correctly during heapify
- Confusing min-heap with max-heap
- Leaving original array unchanged
function heapify(arr: number[], n: number, i: number) {
let largest = i;
let left = 2 * i + 1;
let 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) {
[arr[i], arr[largest]] = [arr[largest], arr[i]];
heapify(arr, n, largest);
}
}
function buildHeap(arr: number[]) {
let n = arr.length;
for (let i = 0; i <= Math.floor(n / 2); i++) {
heapify(arr, n, i);
}
}
What is the error in this code?Solution
Step 1: Analyze buildHeap loop range
The loop runs from 0 up to Math.floor(n/2), but heapify must start from last non-leaf node down to root.Step 2: Correct loop direction and range
Loop should be: for(let i = Math.floor(n/2) - 1; i >= 0; i--) to ensure all subtrees heapify properly.Final Answer:
The loop in buildHeap should run from Math.floor(n/2)-1 down to 0 -> Option AQuick Check:
Heapify bottom-up loop direction matters [OK]
- Looping heapify top-down instead of bottom-up
- Incorrect child index calculations
- Not swapping elements during heapify
arr = [4, 10, 3, 5, 1, 2]. After building a min-heap using heapify, what will be the array representation?Solution
Step 1: Build min-heap bottom-up
Start heapify from index 2 (Math.floor(6/2)-1): heapify at index 2 swaps 3 and 2 to get [4,10,2,5,1,3].Step 2: Heapify at index 1 and 0
At index 1: children 5 and 1, swap 10 and 1 -> [4,1,2,5,10,3]. At index 0: children 1 and 2, swap 4 and 1 -> [1,4,2,5,10,3].Final Answer:
[1, 4, 2, 5, 10, 3] -> Option CQuick Check:
Min-heap root is smallest element 1 [OK]
- Confusing min-heap with max-heap results
- Not swapping correctly during heapify
- Assuming sorted array equals heap
Ready to prove it?
Pass the test and this pattern moves unknown
