"A heap is a tree on paper but an array in memory. No node objects, no left/right pointers — just arithmetic. That's the secret to why a 'tree' can be one of the fastest structures you'll use."
Completeness Buys You the Array
A binary heap is always a complete binary tree: every level is full except possibly the last, which fills strictly left to right. That shape has no gaps — and a tree with no gaps maps perfectly onto a flat array, level by level, with zero wasted slots. So a heap doesn't need node objects or pointers at all. It's just a Python list, and the 'tree' is a way of interpreting the indices.
Navigation Is Just Arithmetic
This is the formula from the binary-tree lesson, now earning its keep. For the element at index i:
- its left child is at
2i + 1 - its right child is at
2i + 2 - its parent is at
(i − 1) // 2
To 'climb the tree' toward the root, you keep doing i = (i-1)//2. To descend, you double-and-add. No pointer dereferencing, no allocations — moving around the tree is pure integer math on array indices. This is exactly why heap operations are so fast: the structure is contiguous, so the CPU cache stays warm (the array-vs-linked-list lesson, paying off yet again).
Why It Must Stay Complete
The completeness requirement isn't cosmetic — it's what keeps the array gapless and the height at exactly ⌊log₂ n⌋. That's why every heap operation appends to or removes from the end of the array (the next/last leaf position) and then restores order by moving elements up or down. If a heap were allowed to have holes, the index math would break and the height could grow. Completeness is the discipline that guarantees both the tidy array packing and the O(log n) height that makes everything fast.
Pippa's Confession
2i+1 always landed on the left child. The tree didn't disappear; it turned out to have been an array in a costume the whole time. That collapse — tree concept, array reality — is one of my favorite 'oh, it was simpler than I feared' moments in all of DSA.