Build Heap from Array Heapify in DSA Python - Time & Space Complexity
We want to understand how long it takes to build a heap from an unordered array using heapify.
Specifically, how the work grows as the array size increases.
Analyze the time complexity of the following code snippet.
def heapify(arr, n, i):
largest = i
left = 2 * i + 1
right = 2 * i + 2
if left < n and arr[left] > arr[largest]:
largest = left
if right < n and arr[right] > arr[largest]:
largest = right
if largest != i:
arr[i], arr[largest] = arr[largest], arr[i]
heapify(arr, n, largest)
def build_heap(arr):
n = len(arr)
for i in range(n // 2 - 1, -1, -1):
heapify(arr, n, i)
This code builds a max heap from an array by calling heapify on all non-leaf nodes from bottom up.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The heapify function called on each non-leaf node.
- How many times: Called about n/2 times (for each non-leaf node).
- Inside heapify: It may recurse down the tree, but the depth depends on the node's height.
Heapify work depends on node height; nodes near bottom do less work, nodes near top do more.
| 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 is called n/2 times and each call can go down log n levels, so total time is O(n log n)."
[OK] Correct: Most heapify calls are on nodes near the bottom with small height, so they do less work. The total sums up to O(n), not O(n log n).
Knowing that building a heap is O(n) helps you explain efficient data structure setup in interviews confidently.
"What if we used a simple insert operation repeatedly to build the heap instead of heapify? How would the time complexity change?"
Practice
heapify process when building a heap from an array?Solution
Step 1: Understand heap property
The heap property requires each parent node to be greater (max-heap) or smaller (min-heap) than its children.Step 2: Role of heapify
Heapify rearranges elements to ensure this property holds for every subtree starting from a node.Final Answer:
To rearrange the array elements to satisfy the heap property -> Option AQuick Check:
Heapify = Rearrange for heap property [OK]
- Thinking heapify sorts the array
- Confusing heapify with reversing array
- Assuming heapify removes duplicates
heapify function from the heapq module on a list named arr?Solution
Step 1: Identify module and function
Theheapqmodule provides theheapifyfunction to convert a list into a heap.Step 2: Correct function call syntax
The correct syntax isheapq.heapify(arr)after importingheapq.Final Answer:
heapq.heapify(arr) -> Option CQuick Check:
heapq.heapify(list) is correct call [OK]
- Using wrong order like heapify.heapq(arr)
- Calling heapify as a method on list
- Assigning heapify function instead of calling
import heapq arr = [3, 1, 6, 5, 2, 4] heapq.heapify(arr) print(arr)
Solution
Step 1: Understand heapq.heapify behavior
heapq.heapify converts list into a min-heap, smallest element at root (index 0).Step 2: Apply heapify on given list
After heapify, the list becomes [1, 2, 4, 5, 3, 6], which satisfies min-heap property.Final Answer:
[1, 2, 4, 5, 3, 6] -> Option BQuick Check:
heapify(min-heap) = [1, 2, 4, 5, 3, 6] [OK]
- Expecting sorted list instead of heap order
- Confusing max-heap with min-heap output
- Assuming original list order remains
def build_heap(arr):
n = len(arr)
for i in range(n):
heapify(arr, i, n)
def heapify(arr, i, n):
largest = i
left = 2 * i + 1
right = 2 * i + 2
if left < n and arr[left] > arr[largest]:
largest = left
if right < n and arr[right] > arr[largest]:
largest = right
if largest != i:
arr[i], arr[largest] = arr[largest], arr[i]
heapify(arr, largest, n)
arr = [4, 10, 3, 5, 1]
build_heap(arr)
print(arr)Solution
Step 1: Analyze build_heap loop range
Heap building requires heapify calls from last non-leaf node down to root, i.e., from n//2 - 1 down to 0.Step 2: Identify incorrect loop direction
The code loops from 0 to n, which is incorrect and misses proper heapify order.Final Answer:
The loop should run from n//2 - 1 down to 0, not from 0 to n -> Option AQuick Check:
Build heap loop must go bottom-up [OK]
- Looping top-down instead of bottom-up
- Confusing min-heap and max-heap logic
- Forgetting to swap elements in heapify
arr = [9, 4, 7, 1, -2, 6, 5], you want to build a max-heap using the heapify method. Which sequence of indices should you call heapify on to build the heap correctly?Solution
Step 1: Identify last non-leaf node
For array length 7, last non-leaf node is at index 7//2 - 1 = 2.Step 2: Correct heapify call order
Heapify must be called from index 2 down to 0 to ensure all subtrees satisfy max-heap property.Final Answer:
From index len(arr)//2 - 1 down to 0 in descending order -> Option DQuick Check:
Heapify bottom-up from last parent to root [OK]
- Calling heapify in ascending order
- Calling heapify only on root
- Calling heapify on all indices including leaves
Ready to prove it?
Pass the test and this pattern moves unknown
