Binary Heaps

A binary heap is a data structure, based upon a complete binary tree, that allows the first item in an ordered set to be quickly extracted. Heaps are used in several popular algorithms, including the heapsort method for ordering elements in a collection.

Adding Items to a Heap

Heaps are not static data structures. They allow items to be added and removed as required. However, it is essential that these processes are performed correctly in order that the heap remains valid.

Adding an item to a heap is an O(log n) process. We start by adding the new item to the data structure in the next available node position. This is either directly to the right of the final leaf node or, if the last level of the tree is full, in the leftmost position in a new level. Adding the node in any other position would mean that the binary tree would no longer be complete.

In the image below we've added the value 3 to the heap we saw in the previous figure. This has broken the ordering constraint, as the 3 is lower value than its parent node's 8.

Bubbling Up

To fix the ordering of the heap we use a process known as bubbling up. This is where we recursively compare the new node with its parent. If the two are in the incorrect order they are swapped. The inserted node is then compared to, and potentially swapped with, its new parent. This process continues until no swap is required or the new value reaches the root node. At this point the heap is restored.

In our sample heap the 3 and 8 are incorrectly ordered so are swapped.

After the swap, the 3 is compared with its new parent node, which holds a 4. This is incorrectly ordered so the two values are exchanged. The new node has no further parents so the process is complete and the heap is valid.

Extracting the Root Node

When you remove items from a heap you always take the root node, as it is the first in the ordered sequence. Once removed, there is a gap in the binary tree that must be filled. Again, this is an O(log n) operation.

Taking the root from our original sample heap returns 4 and leaves a gap, as shown below.

To fill the gap we need to move one of the remaining nodes to the root. The only node that we can use for this is the final leaf node. Moving any other node would leave a new hole that meant our binary tree was no longer complete.

Trickling Down

With the leaf node moved to replace the removed root, our heap is again broken due to the ordering constraint. To fix this we use a process known as trickling down. This is similar to bubbling up. First we compare the node with its children. In the case of a min heap, if the node has a larger value than either child it must be moved. It is therefore swapped with the smaller of the two child nodes. We can't swap with the larger child as this would move the child into a position where it was out of order compared to its previous neighbour. If the node only has one child and this has a lower value, it will be swapped.

This trickling down process is repeated until the node's children are in the correct order with respect to their shared parent or until the value is trickled down to be a leaf node.

In our example we need to swap the 9 with its smallest child, which is the 5 to its left.

The moved 9 is then compared with its children. It is still not correctly ordered so it is exchanged with the lower of the two child values. At this point the 9 has become a leaf node so the heap is restored.