Skip to content

Instantly share code, notes, and snippets.

@mimshins
Last active February 12, 2025 11:45
Show Gist options
  • Save mimshins/edd2d8be3d66b797724c956e44d99479 to your computer and use it in GitHub Desktop.
Save mimshins/edd2d8be3d66b797724c956e44d99479 to your computer and use it in GitHub Desktop.
Heapify: creating a heap from array
const hasCorrectOrder = (parent: number, child: number, mode: "min" | "max"): boolean => {
if (mode === "max") return parent >= child;
return parent <= child;
};
const heapifyUp = (heap: number[], mode: "min" | "max", startIdx?: number): void => {
let idx = startIdx ?? heap.length - 1;
let parentIndex = Math.floor((idx - 1) / 2);
while (idx >= 0 && parentIndex >= 0 && !hasCorrectOrder(heap[parentIndex], heap[idx], mode)) {
const temp = array[idx];
array[idx] = array[parentIdx];
array[parentIdx] = temp;
idx = parentIndex;
parentIndex = Math.floor((idx - 1) / 2);
}
};
const heapifyDown = (heap: number[], mode: "min" | "max", startIdx?: number) => {
const idx = startIdx ?? 0;
const leftIdx = idx * 2 + 1;
const rightIdx = idx * 2 + 2;
let largestOrSmallestIdx = NaN;
if (
leftIdx < array.length &&
!hasCorrectOrder(array[idx], array[leftIdx], mode)
) {
largestOrSmallestIdx = leftIdx;
}
if (
rightIdx < array.length &&
(
Number.isNaN(largestOrSmallestIdx) && !hasCorrectOrder(array[idx], array[rightIdx], mode) ||
!Number.isNaN(largestOrSmallestIdx) && !hasCorrectOrder(array[leftIdx], array[rightIdx], mode)
)
) {
largestOrSmallestIdx = rightIdx;
}
if (largestOrSmallestIdx !== idx) {
const temp = array[idx];
array[idx] = array[largestOrSmallestIdx];
array[largestOrSmallestIdx] = temp;
heapifyDown(largestOrSmallestIdx);
}
};
const insert = (heap: number[], item: number, mode: "max" | "min") => {
heap.push(item);
heapifyUp(heap, mode);
}
const deleteRoot = (heap: number[], mode: "max" | "min"): number | null => {
if (heap.length === 0) return null;
const root = heap[0];
const last = heap.pop();
if (heap.length > 0) {
heap[0] = last;
heapifyDown(heap, mode);
}
return root;
}
const heapify = (array: number[], mode: "max" | "min"): number[] => {
// Non-leaf nodes are in the first half
for (let i = Math.floor(array.length / 2) - 1; i >= 0; i--) {
heapifyDown(array, mode, i);
}
return array;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment