Heaps are a type of data structure, defined as an array of elements such that it functions according to a heap shape property, such that the heap is an almost complete binary tree (where the last row isn’t full), and the heap order property, which is a specific criterion the heap may fulfil to be valid.
Two common types of heaps are min-heaps and max-heaps, which have the property and , respectively.
For a max heap, the maximum element is at the root.
The heap shape property allows us to index:
The height of a node in a heap is the number of edges on the longest simple downwards path from the node to a leaf. The height of the heap is the height of its root. Because we talk about a binary heap, its height is .
Operations
There are a few operations we want to implement for a max heap:
- Inserting a new element.
- Getting the maximum element.
- Maintaining the max heap property (which runs in ).
The heapify function enforces the heap order property if it’s violated, with runtime . The max heapify function effectively pushes down smaller nodes.
The build-max-heap function constructs a max heap. It starts at the halfway point in the array because all elements to the right of floor(n / 2)
are leaf nodes. Then, we work our way up the heap.
Its time complexity is naively , which is a correct upper bound, but not asymptotically tight. However, we can construct a tighter bound:
- At height , there are at most nodes. Since we work our way up, the number of nodes at each level decreases exponentially (half the nodes of the previous iteration’s level).
- This means the number of nodes that require a heapify decreases as we move up the tree. i.e., at the bottom, we do calls to max-heapify, then , then .
- Basically, the premise that max-heapify requires is incorrect. It will never swap all the way down to the leaves (at each subtree, it only requires at most one swap).
- The height of the heap is .
- Then the runtime is the following. The sum converges absolutely.
Heapsort also relies on heap properties.
See also
- Heap memory, a different construct in programming languages for dynamically allocated, often garbage collected memory
- Priority queue, an abstract data type typically implemented with a heap