# Heap (priority queue)
A type of tree that maintain a weak ordering
Fill in each node from left to right and maintain the heap property (weak ordering to max or min)
# Addition
Add new node to the very bottom and then bubble up (by swapping above) until the heap property is restored
# Deletion
Remove the node, swap the lowest node in it's place and heapify down
# Min Heap
Top node is the smallest
20
| |
30 100
| | | |
31 80 3000 1001
# Max Heap
Top node is the largest
# ArrayList Representation
It can be helpful to represent heaps in an array list so accessing elements at the end is easier.
[0, 1, 2, 3, 4, 5, 6, 7, 8]
Children can be found with this function:
2i + 1 === left child
2i + 2 === right child
And a nodes parent can be found with:
Math.floor((i - 1)/2)
Insert and delete operations have a worst case runtime of O(logn) because the depth of the tree will always be logn
# Implementation (Min Heap)
class MinHeap {
public length: number;
private data: number[];
constructor() {
this.data = [];
this.length = 0;
}
insert(value: number): void {
this.data[this.length] = value;
this.heapifyUp(this.length);
this.length++;
}
delete(): number | undefined {
if (this.length <= 0) return undefined;
const out = this.data[0];
this.length--;
if (this.length === 0) {
this.data = [];
return out;
}
this.data[0] = this.data[this.length];
this.heapifyDown(0);
return out;
}
private heapifyUp(idx: number): void {
if (idx === 0) return;
const val = thid.data[idx];
const pidx = this.parent(idx);
const pval = this.data[pidx];
if (pval > val) {
// swap
this.data[idx] = pval;
this.data[pidx] = val;
this.heapifyUp(pidx);
}
}
private heapifyDown(idx: number): void {
const lidx = this.leftChild(idx);
const ridx = this.rightChild(idx);
if (idx >= this.length || lidx >= this.length) return;
const lval = this.data[lidx];
const rval = this.data[ridx];
const val = this.data[idx];
if (lval > rval && val > rval) {
this.data[idx] = rval;
this.data[ridx] = val;
this.heapifyDown(ridx);
} else if (rval > lval && val > lval) {
this.data[idx] = lval;
this.data[lidx] = val;
this.heapifyDown(lidx);
}
}
private parent(idx: number): number {
return Math.floor((idx - 1) / 2);
}
private leftChild(idx: number): number {
return idx * 2 + 1;
}
private rightChild(idx: number): number {
return idx * 2 + 2;
}
}