0
0
DSA Javascriptprogramming

Build Heap from Array Heapify in DSA Javascript

Choose your learning style9 modes available
Mental Model
We turn an unordered list into a heap by fixing each parent node from the bottom up so the heap property holds everywhere.
Analogy: Imagine stacking boxes so that bigger boxes are always below smaller boxes. We start fixing from the bottom shelves up to the top to make sure the stack is stable.
Array: [4, 10, 3, 5, 1]
Heap tree:
       4
     /   \
   10     3
  /  \
 5    1
Dry Run Walkthrough
Input: array: [4, 10, 3, 5, 1]
Goal: Convert the array into a max heap where every parent is bigger than its children
Step 1: Start heapify from last parent index (1), fix subtree rooted at index 1
[4, 10, 3, 5, 1]
Why: We start from last parent because leaves are already heaps
Step 2: Compare node 10 with children 5 and 1, no swap needed
[4, 10, 3, 5, 1]
Why: Parent 10 is already bigger than children, subtree is heap
Step 3: Move to parent index 0, fix subtree rooted at 4
[4, 10, 3, 5, 1]
Why: We fix from bottom up to ensure heap property
Step 4: Compare 4 with children 10 and 3, swap 4 with 10
[10, 4, 3, 5, 1]
Why: Parent must be bigger, so swap with largest child
Step 5: Fix subtree rooted at index 1 (value 4), compare with children 5 and 1, swap 4 with 5
[10, 5, 3, 4, 1]
Why: After swap, subtree might break heap, so fix recursively
Step 6: Fix subtree rooted at index 3 (value 4), no children to compare
[10, 5, 3, 4, 1]
Why: Leaf node reached, heap property holds
Result:
Final heap array: [10, 5, 3, 4, 1]
Annotated Code
DSA Javascript
class MaxHeap {
  constructor(array) {
    this.heap = array;
    this.buildHeap();
  }

  buildHeap() {
    const n = this.heap.length;
    // Start from last parent node and heapify down to root
    for (let i = Math.floor(n / 2) - 1; i >= 0; i--) {
      this.heapify(i);
    }
  }

  heapify(i) {
    const n = this.heap.length;
    let largest = i;
    const left = 2 * i + 1;
    const right = 2 * i + 2;

    // Check if left child is larger
    if (left < n && this.heap[left] > this.heap[largest]) {
      largest = left;
    }

    // Check if right child is larger
    if (right < n && this.heap[right] > this.heap[largest]) {
      largest = right;
    }

    // If largest is not parent, swap and heapify subtree
    if (largest !== i) {
      [this.heap[i], this.heap[largest]] = [this.heap[largest], this.heap[i]];
      this.heapify(largest);
    }
  }

  printHeap() {
    console.log(this.heap.join(', '));
  }
}

// Driver code
const array = [4, 10, 3, 5, 1];
const maxHeap = new MaxHeap(array);
maxHeap.printHeap();
for (let i = Math.floor(n / 2) - 1; i >= 0; i--) {
start heapify from last parent to root
this.heapify(i);
fix subtree rooted at i to maintain heap property
if (left < n && this.heap[left] > this.heap[largest]) {
check if left child is bigger than current largest
if (right < n && this.heap[right] > this.heap[largest]) {
check if right child is bigger than current largest
if (largest !== i) {
if parent is not largest, swap and heapify child subtree
this.heapify(largest);
recursively fix subtree after swap
OutputSuccess
10, 5, 3, 4, 1
Complexity Analysis
Time: O(n) because heapify is called on n/2 nodes and each call takes O(log n) worst but overall sums to O(n)
Space: O(1) because heapify is done in place without extra arrays
vs Alternative: Naive approach inserting elements one by one into heap is O(n log n), so this bottom-up heapify is faster
Edge Cases
empty array
buildHeap does nothing and heap remains empty
DSA Javascript
for (let i = Math.floor(n / 2) - 1; i >= 0; i--) {
array with one element
heapify runs once but no swaps needed, heap is the same
DSA Javascript
for (let i = Math.floor(n / 2) - 1; i >= 0; i--) {
array with all equal elements
no swaps happen, heap property holds trivially
DSA Javascript
if (largest !== i) {
When to Use This Pattern
When you need to build a heap quickly from an unordered array, use bottom-up heapify starting from last parent to root to efficiently enforce heap property.
Common Mistakes
Mistake: Starting heapify from index 0 instead of last parent causes unnecessary work and incorrect heap
Fix: Start heapify from Math.floor(n/2) - 1 down to 0 to only fix parents
Mistake: Not recursively heapifying after swap breaks heap property in subtrees
Fix: Call heapify recursively on the swapped child's index
Summary
Builds a max heap from an unordered array by fixing heap property from bottom up.
Use when you want to convert an array into a heap efficiently before heap operations.
Start heapify from last parent node down to root, recursively fixing subtrees after swaps.