It's easier to look at a heap as a tree:
1
3 9
7 5
where each node is less than either of its children, but the order of the children is irrelevant (which distinguishes a heap from a binary search tree).
A complete tree admits a simple embedding in an array by numbering the nodes in breadth-first order, starting with the root as node 1.
1(1)
3(2) 9(3)
7(4) 5(5)
With such an embedding, the following relations hold:
li[i] <= li[2*i]
li[i] <= li[2*i + 1]
2*i
and 2*i + 1
are the formulas for computing the left and right child, respectively, of the node at position i
:
+--+--+
| v v
[1, 3, 9, 7, 5]
| ^ ^
+-----+--+
(You can specify these properties for a 0-based array, but it's simpler to think about with 1-based arrays.)
Such a list is heap-ordered (which is weaker than being sorted, as all sorted lists are also heap-ordered), and allows the standard heap methods to be implemented efficiently.