@amaui/heap
Version:
119 lines (118 loc) • 5.38 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AmauiHeap = exports.AmauiNode = void 0;
const is_1 = __importDefault(require("@amaui/utils/is"));
class AmauiNode {
constructor(value) {
this.value = value;
}
}
exports.AmauiNode = AmauiNode;
class AmauiHeap {
constructor(variant = 'min') {
this.variant = variant;
this.values = [];
}
static get min() { return new AmauiHeap('min'); }
static get max() { return new AmauiHeap('max'); }
static make(value, variant) { return new AmauiHeap(variant).make(value); }
static left(index) { return (2 * index) + 1; }
static right(index) { return (2 * index) + 2; }
static parent(index) { return Math.floor((index - 1) / 2); }
static isPriority(index) { return index === 0; }
static isLeft(index) { return !!(index !== 0 && index % 2); }
static isRight(index) { return !!(index !== 0 && !(index % 2)); }
static isLeaf(index, values) {
return index >= Math.floor(values.length / 2) && index <= values.length - 1;
}
get array() { return this.values.map(item => item.value); }
get first() { return this.values[0]; }
get leafs() {
return this.values.filter((_, index) => AmauiHeap.isLeaf(index, this.values));
}
get remove() {
if (!this.values.length)
return;
const first = this.first;
const end = this.values.pop();
this.values[0] = end;
// Heapify down first values value
this.heapifyDown();
return first;
}
add(value) {
const amauiNode = value instanceof AmauiNode ? value : new AmauiNode(value);
// Push to the end of the values array
this.values.push(amauiNode);
// Heapify up the added values value
this.heapifyUp();
return this;
}
swap(index, index1) {
[this.values[index], this.values[index1]] = [this.values[index1], this.values[index]];
return this;
}
make(value) {
this.values = value.map(value_ => value_ instanceof AmauiNode ? value_ : new AmauiNode(value_));
for (let i = Math.floor(this.values.length / 2); i >= 0; i--) {
this.heapifyDown(i);
}
return this;
}
forEach(method) {
if ((0, is_1.default)('function', method))
this.values.forEach((value, index) => {
const parent = this.values[AmauiHeap.parent(index)];
const left = this.values[AmauiHeap.left(index)];
const right = this.values[AmauiHeap.right(index)];
const isPriority = AmauiHeap.isPriority(index);
const isLeaf = AmauiHeap.isLeaf(index, this.values);
const isLeft = AmauiHeap.isLeft(index);
const isRight = AmauiHeap.isRight(index);
method(value, index, parent, left, right, isPriority, isLeaf, isLeft, isRight);
});
}
heapifyUp(index_ = this.values.length - 1) {
var _a, _b, _c, _d;
if (this.values.length > 0) {
let index = index_;
let parentIndex = AmauiHeap.parent(index);
while (index > 0 &&
(this.variant === 'min' ?
((_a = this.values[parentIndex]) === null || _a === void 0 ? void 0 : _a.value) > ((_b = this.values[index]) === null || _b === void 0 ? void 0 : _b.value) :
((_c = this.values[parentIndex]) === null || _c === void 0 ? void 0 : _c.value) < ((_d = this.values[index]) === null || _d === void 0 ? void 0 : _d.value))) {
// Swap parent and child
this.swap(parentIndex, index);
index = parentIndex;
parentIndex = AmauiHeap.parent(index);
}
}
}
heapifyDown(index_ = 0) {
var _a, _b, _c, _d, _e, _f, _g, _h;
if (!AmauiHeap.isLeaf(index_, this.values)) {
const index = index_;
const left = AmauiHeap.left(index);
const right = AmauiHeap.right(index);
let swapIndex = index;
// Swap left and parent if swap to be made
if (this.variant === 'min' ?
((_a = this.values[left]) === null || _a === void 0 ? void 0 : _a.value) < ((_b = this.values[swapIndex]) === null || _b === void 0 ? void 0 : _b.value) :
((_c = this.values[left]) === null || _c === void 0 ? void 0 : _c.value) > ((_d = this.values[swapIndex]) === null || _d === void 0 ? void 0 : _d.value))
swapIndex = left;
// Swap right and parent if swap to be made
if (this.variant === 'min' ?
((_e = this.values[right]) === null || _e === void 0 ? void 0 : _e.value) < ((_f = this.values[swapIndex]) === null || _f === void 0 ? void 0 : _f.value) :
((_g = this.values[right]) === null || _g === void 0 ? void 0 : _g.value) > ((_h = this.values[swapIndex]) === null || _h === void 0 ? void 0 : _h.value))
swapIndex = right;
if (index !== swapIndex) {
this.swap(index, swapIndex);
this.heapifyDown(swapIndex);
}
}
}
}
exports.AmauiHeap = AmauiHeap;