0
0
DSA Goprogramming

Heap Extract Min or Max Bubble Down in DSA Go

Choose your learning style9 modes available
Mental Model
When we remove the top value from a heap, we replace it with the last item and then push it down to fix the heap order.
Analogy: Imagine a line of kids holding balloons by height order. If the tallest kid leaves, the last kid steps in front but might be shorter, so they move down the line until everyone is taller behind them.
       1
      / \
     3   5
    / \  /
   7  9 8

(Heap as a tree with min at root)
Dry Run Walkthrough
Input: min-heap: [1, 3, 5, 7, 9, 8], extract min
Goal: Remove the smallest element (1) and restore heap order by pushing down the replacement
Step 1: Remove root (1), replace it with last element (8)
[8, 3, 5, 7, 9] (array form of heap)
Why: We remove the top and fill the gap with the last element to keep complete tree shape
Step 2: Compare 8 with children 3 and 5; swap with smallest child 3
[3, 8, 5, 7, 9]
Why: 8 is bigger than 3, so swap to maintain min-heap property
Step 3: Compare 8 with its new children 7 and 9; swap with smallest child 7
[3, 7, 5, 8, 9]
Why: 8 is bigger than 7, so swap again to fix heap order
Step 4: 8 has no children now, stop bubbling down
[3, 7, 5, 8, 9]
Why: Reached leaf, heap order restored
Result:
[3, 7, 5, 8, 9] (heap after extract min and bubble down)
Annotated Code
DSA Go
package main

import (
	"fmt"
)

type MinHeap struct {
	arr []int
}

func (h *MinHeap) bubbleDown(index int) {
	n := len(h.arr)
	for {
		left := 2*index + 1
		right := 2*index + 2
		smallest := index

		if left < n && h.arr[left] < h.arr[smallest] {
			smallest = left
		}
		if right < n && h.arr[right] < h.arr[smallest] {
			smallest = right
		}

		if smallest == index {
			break // heap property restored
		}

		h.arr[index], h.arr[smallest] = h.arr[smallest], h.arr[index]
		index = smallest // continue bubbling down
	}
}

func (h *MinHeap) ExtractMin() (int, bool) {
	n := len(h.arr)
	if n == 0 {
		return 0, false // empty heap
	}
	min := h.arr[0]
	h.arr[0] = h.arr[n-1] // move last to root
	h.arr = h.arr[:n-1]   // remove last
	h.bubbleDown(0)       // fix heap
	return min, true
}

func main() {
	h := MinHeap{arr: []int{1, 3, 5, 7, 9, 8}}
	min, ok := h.ExtractMin()
	if ok {
		fmt.Printf("Extracted min: %d\n", min)
		fmt.Printf("Heap after extract: %v\n", h.arr)
	} else {
		fmt.Println("Heap is empty")
	}
}
h.arr[0] = h.arr[n-1] // move last to root
Replace root with last element to keep complete tree shape
h.arr = h.arr[:n-1] // remove last
Remove last element since it's moved to root
h.bubbleDown(0) // fix heap
Restore heap order by pushing down the new root
if left < n && h.arr[left] < h.arr[smallest] { smallest = left }
Find smaller child to swap with
if right < n && h.arr[right] < h.arr[smallest] { smallest = right }
Check right child for smaller value
if smallest == index { break }
Stop if heap property is restored
h.arr[index], h.arr[smallest] = h.arr[smallest], h.arr[index]
Swap current node with smaller child
index = smallest // continue bubbling down
Move down to child's position
OutputSuccess
Extracted min: 1 Heap after extract: [3 7 5 8 9]
Complexity Analysis
Time: O(log n) because bubble down moves down the height of the heap which is log n
Space: O(1) because we do swaps in place without extra storage
vs Alternative: Naive approach would reorder the entire heap or array, costing O(n log n), so bubble down is much faster
Edge Cases
empty heap
ExtractMin returns false and zero value, no crash
DSA Go
if n == 0 { return 0, false // empty heap }
heap with one element
ExtractMin returns that element and heap becomes empty
DSA Go
h.arr = h.arr[:n-1]   // remove last
heap where last element is larger than root
Bubble down swaps as needed to restore heap order
DSA Go
bubbleDown function swaps with smaller child until heap property restored
When to Use This Pattern
When you see a problem asking to remove the top element from a heap and keep it valid, use extract + bubble down to restore order efficiently.
Common Mistakes
Mistake: Not swapping with the smallest child during bubble down in a min-heap
Fix: Always compare both children and swap with the smallest to maintain heap property
Mistake: Forgetting to remove the last element after moving it to root
Fix: Slice the array to remove last element after replacement
Summary
Removes the top element from a heap and restores heap order by pushing down the replacement.
Use when you want to extract min or max from a heap and keep it valid.
The key is to replace root with last element and bubble it down by swapping with the smaller (or larger) child until order is fixed.