0
0
DSA Javascriptprogramming

Why Heap Exists and What Sorted Array Cannot Do Efficiently in DSA Javascript - Why This Pattern

Choose your learning style9 modes available
Mental Model
A heap helps quickly find and remove the smallest or largest item, which a sorted array cannot do efficiently when items change.
Analogy: Imagine a messy pile of papers where you want the most important one fast. A heap is like a special stack that always keeps the top paper the most important, so you grab it quickly without sorting everything again.
Sorted Array: [1] -> [3] -> [5] -> [7] -> [9]
Heap (min-heap):
      1
     / \
    3   5
   / \
  7   9
Dry Run Walkthrough
Input: Sorted array: [1, 3, 5, 7, 9], remove smallest and add 2
Goal: Show why removing smallest and adding a new number is slow in sorted array but fast in heap
Step 1: Remove smallest element (1) from sorted array
[3] -> [5] -> [7] -> [9]
Why: Removing smallest means removing first element and shifting all others left
Step 2: Add new element (2) to sorted array and keep sorted
[2] -> [3] -> [5] -> [7] -> [9]
Why: We must find correct place for 2 and shift elements to insert it
Step 3: Remove smallest element (1) from heap
Heap after removing 1 and reordering:
      3
     / \
    7   5
   / 
  9
Why: Heap removes root and reorders quickly without shifting all elements
Step 4: Add new element (2) to heap and reorder
Heap after adding 2 and reordering:
      2
     / \
    3   5
   / \
  9   7
Why: Heap inserts at bottom and bubbles up to keep order fast
Result:
Sorted Array final: [2] -> [3] -> [5] -> [7] -> [9]
Heap final:
      2
     / \
    3   5
   / \
  9   7
Annotated Code
DSA Javascript
class MinHeap {
  constructor() {
    this.heap = []
  }

  insert(val) {
    this.heap.push(val) // add at end
    this.bubbleUp() // reorder up
  }

  bubbleUp() {
    let idx = this.heap.length - 1
    while (idx > 0) {
      let parentIdx = Math.floor((idx - 1) / 2)
      if (this.heap[parentIdx] <= this.heap[idx]) break
      ;[this.heap[parentIdx], this.heap[idx]] = [this.heap[idx], this.heap[parentIdx]] // swap
      idx = parentIdx // move up
    }
  }

  extractMin() {
    if (this.heap.length === 0) return null
    if (this.heap.length === 1) return this.heap.pop()
    const min = this.heap[0]
    this.heap[0] = this.heap.pop() // move last to root
    this.bubbleDown() // reorder down
    return min
  }

  bubbleDown() {
    let idx = 0
    const length = this.heap.length
    while (true) {
      let leftIdx = 2 * idx + 1
      let rightIdx = 2 * idx + 2
      let swapIdx = null

      if (leftIdx < length && this.heap[leftIdx] < this.heap[idx]) {
        swapIdx = leftIdx
      }
      if (rightIdx < length && this.heap[rightIdx] < (swapIdx === null ? this.heap[idx] : this.heap[leftIdx])) {
        swapIdx = rightIdx
      }
      if (swapIdx === null) break
      ;[this.heap[idx], this.heap[swapIdx]] = [this.heap[swapIdx], this.heap[idx]]
      idx = swapIdx
    }
  }

  print() {
    return this.heap.join(' -> ')
  }
}

// Driver code to show difference
// Sorted array operations
let sortedArr = [1, 3, 5, 7, 9]
// Remove smallest (shift)
sortedArr.shift()
// Insert 2 and keep sorted
sortedArr.push(2)
sortedArr.sort((a, b) => a - b)

// Heap operations
const heap = new MinHeap()
[1, 3, 5, 7, 9].forEach(v => heap.insert(v))
heap.extractMin() // remove smallest
heap.insert(2) // add 2

console.log('Sorted Array final:', sortedArr.join(' -> '))
console.log('Heap final:', heap.print())
this.heap.push(val) // add at end
insert new element at bottom of heap
while (idx > 0) { ... swap ... idx = parentIdx }
bubble up new element to restore heap order
const min = this.heap[0] this.heap[0] = this.heap.pop()
remove root and replace with last element
while (true) { ... swapIdx ... swap ... idx = swapIdx }
bubble down root element to restore heap order
sortedArr.shift()
remove smallest from sorted array by shifting all elements
sortedArr.push(2) sortedArr.sort((a, b) => a - b)
insert new element and re-sort array
OutputSuccess
Sorted Array final: 2 -> 3 -> 5 -> 7 -> 9 Heap final: 2 -> 3 -> 5 -> 9 -> 7
Complexity Analysis
Time: O(n) for removing smallest and inserting in sorted array because shifting and sorting take linear time; O(log n) for heap operations because bubbling up/down takes logarithmic time
Space: O(n) for both because they store all elements
vs Alternative: Heap is faster than sorted array for frequent insertions and removals because it avoids full array shifts and re-sorting
Edge Cases
empty heap or array
extractMin returns null or shift returns undefined without error
DSA Javascript
if (this.heap.length === 0) return null
single element in heap or array
extractMin returns the only element correctly
DSA Javascript
if (this.heap.length === 1) return this.heap.pop()
When to Use This Pattern
When you need to repeatedly get and remove the smallest or largest item quickly while also adding new items, reach for a heap because it keeps order efficiently without full sorting.
Common Mistakes
Mistake: Trying to remove smallest from a sorted array by just popping last element
Fix: Remove smallest by shifting first element, but note this is slow; better use a heap
Mistake: Inserting new element in sorted array without re-sorting or placing correctly
Fix: Always insert and then re-sort or find correct position to keep array sorted
Summary
Shows why heaps exist to efficiently remove and add smallest/largest elements.
Use heaps when you need fast repeated access to min or max with dynamic data.
Heaps keep partial order so insertions and removals are fast without full sorting.