08-heaps
Min-Heap Pop (Sift Down)
Remove the minimum value, move the last item to the root, and sift downward.
Algorithm
Steps
- Store the heap in an array.
- Compare parent and child indexes instead of building explicit tree nodes.
- Swap only when the heap order is violated.
- Print the deterministic final heap state for replay comparison.
sift down
After removing the root, the last value moves to the root and swaps with the smaller child until order is restored.
Complexity
- Time: O(log n)
- Space: O(1) extra
Visual walkthrough
R DSA Implementation
basic.R
list_string <- function(values) paste0("[", paste(values, collapse = ", "), "]")
heap_insert <- function(heap, value) {
heap <- c(heap, value)
child <- length(heap)
while (child > 1) {
parent <- floor(child / 2)
if (heap[parent] <= heap[child]) break
tmp <- heap[parent]; heap[parent] <- heap[child]; heap[child] <- tmp
child <- parent
}
heap
}
heap_pop <- function(heap) {
smallest <- heap[1]
heap[1] <- heap[length(heap)]
heap <- heap[-length(heap)]
parent <- 1
while (TRUE) {
left <- parent * 2
right <- left + 1
if (left > length(heap)) break
child <- left
if (right <= length(heap) && heap[right] < heap[left]) child <- right
if (heap[parent] <= heap[child]) break
tmp <- heap[parent]; heap[parent] <- heap[child]; heap[child] <- tmp
parent <- child
}
list(value = smallest, heap = heap)
}
heap <- c(1, 4, 2, 9, 6, 7)
result <- heap_pop(heap)
cat(result$value, " -> ", list_string(result$heap), "\n", sep = "")
Implementation notes
heap <- c(1, 4, 2, 9, 6, 7)is the starting min-heap vector. This lesson uses R's 1-based indexes.- The output path calls
result <- heap_pop(heap).heap_insert()is present in the shared file, but it is not used for this lesson's printed result. heap_pop()storessmallest <- heap[1], moves the last value to the root withheap[1] <- heap[length(heap)], then removes the old last slot withheap <- heap[-length(heap)].- The trace shows that as popped value
1and heap[7, 4, 2, 9, 6]. - Sift-down starts at
parent <- 1.left <- parent * 2andright <- left + 1are the 1-based child indexes. - The code starts with
child <- left, then switches to the right child whenright <= length(heap) && heap[right] < heap[left]. - At the root,
7has left child4at index2and right child2at index3, so the smaller child is2. if (heap[parent] <= heap[child]) breakstops when min-heap order is valid; otherwise thetmpline swaps parent and child, thenparent <- child.
Replay steps
start: [1, 4, 2, 9, 6, 7]
pop root: 1, move 7 to root -> [7, 4, 2, 9, 6]
swap 7/2: [2, 4, 7, 9, 6]
heap_pop()returnslist(value = smallest, heap = heap), so the output readsresult$valueandresult$heap.cat(result$value, " -> ", list_string(result$heap), "\n", sep = "")prints exactly1 -> [2, 4, 7, 9, 6].
Output
1 -> [2, 4, 7, 9, 6]