Heap (data structure)

For the memory heap, see Memory heap.
A **heap** is a special tree-based data structure. It is based on a complete tree, and satisfies the following **heap properties**:

* **Min-heap**: In a min-heap, *every single node* is *smaller than* all of its descendants.
* **Max-heap**: In a max-heap, *every single node* is *greater than* all of its descendants.

## Binary heap

A **binary heap** is a complete binary tree that satisfies the heap properties.

A binary heap is either a **min-heap** or a **max-heap**.

### Representation of a binary heap as an array

Since a binary heap is a **complete binary tree**, i.e. it is a balanced binary tree with all non-empty nodes generated on the left as much as possible, it can be represented as an array in memory:

* The root of the heap is the first element, i.e. index 0, of the array.
* For each node of index `i` in the array:
	+ Its *parent node index* is **`(i-1) / 2`**.
	+ Its *left child index* is **`i*2 + 1`**.
	+ Its *right child index* is **`i*2 + 2`**.

The traversal order to list all nodes in an array is called "**level-order traversal**".

### Check if a binary tree is a min-heap

Here is the method to check if a binary tree is a min-heap.

We need to do two steps:

1. Check if the binary tree is *complete*.
2. Check if heap property is satisfied *recursively* for every node.

#### Complexity

##### Time complexity

1. Going over the entire binary tree to check completeness takes O(n) time.
2. Checking heap property for each node recursively also takes O(n) time.

So total time complexity is **O(n)**.

##### Space complexity

Stack
1. In the process of checking completeness of the binary tree, the space complexity is O(1).
2. In recursively checking heap property, since a complete binary tree has O(log *n*) height, the space complexity is O(log *n*).

Heap
1. In checking completeness of the binary tree, we have created a BFS queue that may receive a maximum of (n/2) nodes (for a perfect binary tree). So the space complexity is O(*n*).
2. In checking heap property, we have not allocated any new objects. So the space complexity is O(1).

So the total space complexity is **O(n)**.

#### C++ solution

```
//class TreeNode {
// public:
// int value;
// TreeNode\* left;
// TreeNode\* right;
// TreeNode(int v) : value(v), left(nullptr), right(nullptr) {}
//};
class Solution {
private:
 // first check if a binary tree is complete
 static bool isCompleteBinaryTree(TreeNode \*const root) {
 if (root == nullptr) {
 return true;
 }

 std::queue<TreeNode\*> BFSQueue;
 TreeNode \*prev = root;
 BFSQueue.push(root);
 while (!BFSQueue.empty()) {
 TreeNode \*curr = BFSQueue.front();
 BFSQueue.pop();
 TreeNode \*const left = curr->left, \*const right = curr->right;

 // check left child
 if ((prev == nullptr) && (left != nullptr)) {
 return false;
 }
 else {
 prev = left;
 if (left != nullptr) {
 BFSQueue.push(left);
 }
 }
 // check right child
 if ((prev == nullptr) && (right != nullptr)) {
 return false;
 }
 else {
 prev = right;
 if (right != nullptr) {
 BFSQueue.push(right);
 }
 }
 }

 return true;
 }

 // then check if heap property is satisfied recursively
 static bool isMinHeapRecursive(TreeNode\* root) {
 if (root == nullptr) {
 return true;
 }

 TreeNode \*const left = root->left, \*const right = root->right;
 if ((left != nullptr) && (left->value < root->value)) {
 return false;
 }
 if ((right != nullptr) && (right->value < root->value)) {
 return false;
 }
 return isMinHeapRecursive(left) && isMinHeapRecursive(right);
 }

public:
 // entry method
 bool isMinHeap(TreeNode\* root) {
 if (root == nullptr) {
 return true;
 }
 else if (!isCompleteBinaryTree(root)) {
 return false;
 }
 else {
 return isMinHeapRecursive(root);
 }
 }
};

```

#### Java solution

```
/\*\*
 \* public class TreeNode {
 \* public int key;
 \* public TreeNode left;
 \* public TreeNode right;
 \* public TreeNode(int key) {
 \* this.key = key;
 \* }
 \* }
 \*/
public class Solution {
 // first check if a binary tree is complete
 private static boolean isCompleteBinaryTree(final TreeNode root) {
 if (root == null) {
 return true;
 }

 Queue<TreeNode> BFSQueue = new ArrayDeque<>();
 TreeNode prev = root;
 BFSQueue.offer(root);
 while (!BFSQueue.isEmpty()) {
 final TreeNode curr = BFSQueue.poll();
 final TreeNode left = curr.left, right = curr.right;

 // check left child
 if ((prev == null) && (left != null)) {
 return false;
 }
 else {
 prev = left;
 if (left != null) {
 BFSQueue.offer(left);
 }
 }
 // check right child
 if ((prev == null) && (right != null)) {
 return false;
 }
 else {
 prev = right;
 if (right != null) {
 BFSQueue.offer(right);
 }
 }
 }

 return true;
 }

 // then check if heap property is satisfied recursively
 private static boolean isMinHeapRecursive(final TreeNode root) {
 if (root == null) {
 return true;
 }

 final TreeNode left = root.left, right = root.right;
 if ((left != null) && (left.key < root.key)) {
 return false;
 }
 if ((right != null) && (right.key < root.key)) {
 return false;
 }
 return isMinHeapRecursive(left) && isMinHeapRecursive(right);
 }

 // entry method
 public boolean isMinHeap(TreeNode root) {
 if (root == null) {
 return true;
 }
 else if (!isCompleteBinaryTree(root)) {
 return false;
 }
 else {
 return isMinHeapRecursive(root);
 }
 }
}

```

### Operations of a binary heap

Main article: Binary heap operations

 **Update** | Update the value of the node, and then rearrange the nodes so that they satisfy the heap properties.
 **Get top** | Get the top value of the heap, i.e. the minimum value (in a min-heap) or the maximum value (in a max-heap).
 **Pop top** | Remove the element from the top. This is done by first moving the tail of the heap to the top, and then *percolating down* if necessary.
 **Heapify** | Transform an unsorted array into a heap.

## Sample problems

* K-th smallest/largest element in unsorted array
* K-th smallest number in sorted matrix

## External links

* Heap Data Structure (Archive)
* Array Representation Of Binary Heap (Archive)
* Binary Heaps (Archive)