Skip to main content

Heaps (priority queues)

Complete Binary Tree​

Each level of a Complete Binary Tree contains the maximum number of nodes, except possibly the last layer, which must be filled from left to right.

Heap property​

Heap property essentially means that for any given node C, if P is a parent node of C, then:

  • For a max heap: the key of P should be greater than or equal to the key of C.
  • For a min heap: the key of P should be less than or equal to the key of C.

Heaps are stored as arrays​

If a node is placed at index i in array, then given that the resultant index lies within length of the array:

  • Left child would be at (2i+1)th position
  • Right child would be at (2i+2)the position

If a node is placed at index i in array, it's parent node would be located at floor((i-1)/2)th index.

Implementation (Min Heap)​

heappush​

adds the provided newKey into the min-heap named "heap"

function heappush(heap, newKey){
// push the new key
heap.push(newKey);

// get the current index of pushed key
let curr = heap.length-1;

// keep comparing till root is reached or we terminate in middle
while(curr > 0){
let parent = Math.floor((curr-1)/2)
if( heap[curr] < heap[parent] ){
// quick swap
[ heap[curr], heap[parent] ] = [ heap[parent], heap[curr] ]
// update the index of newKey
curr = parent
} else{
// if no swap, break, since we heap is stable now
break
}
}
}

heappop​

removes the smallest key from the min-heap named "heap"

function heappop(heap){
// swap root with last node
const n = heap.length;
[heap[0], heap[n-1]] = [ heap[n-1], heap[0]]

// remove the root i.e. the last item (because of swap)
const removedKey = heap.pop();

let curr = 0;

// keep going till atleast left child is possible for current node
while(2*curr + 1 < heap.length){
const leftIndex = 2*curr+1;
const rightIndex = 2*curr+2;
const minChildIndex = (rightIndex < heap.length && heap[rightIndex] < heap[leftIndex] ) ? rightIndex :leftIndex;
if(heap[minChildIndex] < heap[curr]){
// quick swap, if smaller of two children is smaller than the parent (min-heap)
[heap[minChildIndex], heap[curr]] = [heap[curr], heap[minChildIndex]]
curr = minChildIndex
} else {
break
}
}

// finally return the removed key
return removedKey;
}

heapify​

transforms a pre-existing array into a heap

function percolateDown(heap, index) {
let curr = index;
// keep going down till heap property is established
while (2 * curr + 1 < heap.length) {
const leftIndex = 2 * curr + 1;
const rightIndex = 2 * curr + 2;
const minChildIndex = (rightIndex < heap.length && heap[rightIndex] < heap[leftIndex]) ? rightIndex : leftIndex;
if (heap[minChildIndex] < heap[curr]) {
// quick swap, if smaller of two children is smaller than the parent (min-heap)
[heap[minChildIndex], heap[curr]] = [heap[curr], heap[minChildIndex]]
curr = minChildIndex
} else {
break
}
}
}

function heapify(heap){
const last = Math.floor(heap.length/2 - 1);
for(let i = 0; i <= last; i++){
percolateDown(heap, i)
}
return heap
}

How to make it into a Max Heap​

Max heap is a min heap using negative keys.

Say we have an array const x = [23, 454, 54, 29]

const minHeap = [];
for(let el of x) heappush(minHeap, el);

// min value
const min = heappop(minHeap)
const maxHeap = [];
for(let el of x) heappush(maxHeap, el);

// max value
const max = -heappop(maxHeap)