lgrthms
Version:
Algorithms and data structures for your JavaScript and TypeScript projects 🧑💻
49 lines (48 loc) • 1.91 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.heapSort = void 0;
const Comparator_1 = require("../../utils/Comparator");
const arrays_1 = require("../../utils/arrays");
// O(nlog(n)) time | O(1) space
function heapSort(array, compareFn) {
const comparator = new Comparator_1.Comparator(compareFn);
buildMaxHeap(array, comparator);
for (let lastIndex = array.length - 1; lastIndex > 0; lastIndex--) {
(0, arrays_1.swap)(array, 0, lastIndex);
siftDown(array, 0, lastIndex - 1, comparator);
}
return array;
}
exports.heapSort = heapSort;
function buildMaxHeap(array, comparator) {
const lastIndex = array.length - 1;
const firstParentIndex = getParentIndex(lastIndex);
for (let parentIndex = firstParentIndex; parentIndex >= 0; parentIndex--) {
siftDown(array, parentIndex, lastIndex, comparator);
}
}
function siftDown(array, index, lastIndex, comparator) {
let childOneIndex = getChildIndex(index, lastIndex, 1);
while (childOneIndex !== -1) {
const childTwoIndex = getChildIndex(index, lastIndex, 2);
let childIndexToSwapWith = childOneIndex;
if (childTwoIndex !== -1 && comparator.isGreaterThan(array[childTwoIndex], array[childOneIndex])) {
childIndexToSwapWith = childTwoIndex;
}
if (comparator.isGreaterThan(array[childIndexToSwapWith], array[index])) {
(0, arrays_1.swap)(array, index, childIndexToSwapWith);
index = childIndexToSwapWith;
childOneIndex = getChildIndex(index, lastIndex, 1);
}
else {
break;
}
}
}
function getParentIndex(childIndex) {
return Math.floor((childIndex - 1) / 2);
}
function getChildIndex(parentIndex, lastIndex, childNumber) {
const childIndex = parentIndex * 2 + childNumber;
return childIndex > lastIndex ? -1 : childIndex;
}