Build Heap from Array Heapify in DSA Go - Time & Space Complexity
We want to understand how long it takes to build a heap from an array using heapify.
Specifically, how the work grows as the array size increases.
Analyze the time complexity of the following code snippet.
func buildHeap(arr []int) {
n := len(arr)
for i := n/2 - 1; i >= 0; i-- {
heapify(arr, n, i)
}
}
func heapify(arr []int, n, i int) {
largest := i
left := 2*i + 1
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.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The heapify function called on each non-leaf node.
- How many times: The for loop runs about n/2 times, and each heapify can recurse down the tree.
Heapify work depends on the height of the tree at each node, which varies.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 20-30 operations |
| 100 | About 300-400 operations |
| 1000 | About 4000-5000 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 on n/2 nodes and each takes O(log n), so total is O(n log n)."
[OK] Correct: Most heapify calls are on nodes near the bottom with small height, so total work adds up to O(n), not O(n log n).
Understanding this helps you explain why heap construction is efficient and prepares you for questions on priority queues and sorting.
"What if we called heapify starting from the root down to the leaves 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-based structure where each parent node is greater (max-heap) or smaller (min-heap) than its children.Step 2: Role of heapify
The heapify process rearranges elements to ensure this property holds for every subtree starting from a given node.Final Answer:
To rearrange the array elements to satisfy the heap property -> Option AQuick Check:
Heapify = Rearrange for heap property [OK]
- Confusing heapify with sorting
- Thinking heapify finds max element only
- Assuming heapify reverses array
i in Go when building a max heap from an array arr of size n?Solution
Step 1: Understand heapify function parameters
Heapify usually takes the array, size of heap, and the index to heapify as parameters in that order.Step 2: Match parameter order
heapify(arr, n, i) matches the correct order: array, size, index.Final Answer:
heapify(arr, n, i) -> Option DQuick Check:
heapify(arr, n, i) is correct call [OK]
- Mixing parameter order
- Passing index before array
- Confusing size and index positions
[3, 9, 2, 1, 4, 5], what is the array after building a max heap using heapify from the bottom up?Solution
Step 1: Start heapify from last non-leaf node
Last non-leaf node index = n/2 -1 = 6/2 -1 = 2. Heapify nodes 2, 1, 0 in order.Step 2: Heapify index 2
Node 2 value=2, children 5 (index 5). Swap 2 and 5. Array becomes [3, 9, 5, 1, 4, 2].Step 3: Heapify index 1
Node 1 value=9, children 1 and 4. 9 is largest, no change.Step 4: Heapify index 0
Node 0 value=3, children 9 and 5. Swap 3 and 9. Array becomes [9, 3, 5, 1, 4, 2]. Heapify index 1 again: 3 with children 1 and 4, swap 3 and 4. Final array: [9, 4, 5, 1, 3, 2].Final Answer:
[9, 4, 5, 1, 3, 2] -> Option CQuick Check:
Bottom-up heapify gives [9,4,5,1,3,2] [OK]
- Not heapifying children after swap
- Starting heapify from wrong index
- Confusing max-heap with min-heap
arr. What is the error?
func buildHeap(arr []int) {
n := len(arr)
for i := n / 2; i >= 0; i-- {
heapify(arr, n, i)
}
}Solution
Step 1: Identify correct start index for heapify
Heapify starts from last non-leaf node at index n/2 - 1, not n/2.Step 2: Analyze loop range
Starting at n/2 includes one extra index which is a leaf node, unnecessary and may cause incorrect behavior.Final Answer:
The loop should start from n/2 - 1, not n/2 -> Option BQuick Check:
Start heapify at n/2 - 1 [OK]
- Starting loop at n/2 instead of n/2 - 1
- Loop increment instead of decrement
- Wrong loop condition excluding index 0
[4, 10, 3, 5, 1]. After building a max heap using heapify, you want to insert a new element 15 and maintain the max heap property. Which sequence of operations correctly maintains the heap?Solution
Step 1: Understand insertion in heap
To insert, add element at end, then restore heap by bubbling up (swapping with parent if larger).Step 2: Why bubble up?
Heapify from bottom up is for building heap initially; for insertion, bubbling up fixes heap efficiently.Final Answer:
Append 15, then bubble up the new element until heap property is restored -> Option AQuick Check:
Insert + bubble up maintains heap [OK]
- Using heapify from root after insertion
- Heapifying only root node
- Replacing root without adjusting heap
Ready to prove it?
Pass the test and this pattern moves unknown
