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.
Complexity
- Time: O(log n)
- Space: O(1) extra
sift down
After removing the root, the last value moves to the root and swaps with the smaller child until order is restored.
Visual walkthrough
C++ DSA Implementation
basic.cpp
#include <algorithm>
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
string listString(const vector<int>& values) {
stringstream out; out << "[";
for (size_t i = 0; i < values.size(); i++) { if (i) out << ", "; out << values[i]; }
out << "]"; return out.str();
}
void heapInsert(vector<int>& heap, int value) {
heap.push_back(value);
size_t child = heap.size() - 1;
while (child > 0) {
size_t parent = (child - 1) / 2;
if (heap[parent] <= heap[child]) break;
swap(heap[parent], heap[child]);
child = parent;
}
}
int heapPop(vector<int>& heap) {
int smallest = heap[0];
heap[0] = heap.back(); heap.pop_back();
size_t parent = 0;
while (true) {
size_t left = parent * 2 + 1, right = left + 1;
if (left >= heap.size()) break;
size_t child = left;
if (right < heap.size() && heap[right] < heap[left]) child = right;
if (heap[parent] <= heap[child]) break;
swap(heap[parent], heap[child]);
parent = child;
}
return smallest;
}
int main() { vector<int> heap = {1, 4, 2, 9, 6, 7}; int popped = heapPop(heap); cout << popped << " -> " << listString(heap) << "\n"; }
Output
1 -> [2, 4, 7, 9, 6]
Implementation notes
- In C++, the heap is a
std::vector<int>initialized as{1, 4, 2, 9, 6, 7}and passed by non-const reference toheapPop(vector<int>& heap). int smallest = heap[0]copies the root value for return, thenheap[0] = heap.back(); heap.pop_back();moves7into the root slot and shortens the same vector.- Sift-down indexes are
size_t:left = parent * 2 + 1andright = left + 1. The loop stops when the left child is outsideheap.size()or the parent is already<=the selected child. - The right child is chosen only when it exists and
heap[right] < heap[left]; swaps usestd::swapon vector elements and then continue from that child index. - The trace records
[1, 4, 2, 9, 6, 7], removes1and moves7to[7, 4, 2, 9, 6], then swaps with smaller child2to[2, 4, 7, 9, 6]. std::cout << popped << " -> " << listString(heap) << "\n"prints1 -> [2, 4, 7, 9, 6];listStringbuilds that bracketed vector text withstd::stringstream. Visible allocation is the heap vector storage and formatting buffer; mutation is root replacement,pop_back, and vector element swaps.