malwoden
Version:
   
123 lines • 4.57 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HeapPriorityQueue = void 0;
/**
* HeapPriorityQueue allows for push/pop based on an attribute
* of the inserted objects. The heap based implementation
* underneath has theoretic O(log(n)) insert/pop time and O(c)
* peek time.
*
* Because the bubble up/down might not preserve order within
* items of the same priority, the array-priority-queue can be
* a better though slower choice in some cases.
*/
var HeapPriorityQueue = /** @class */ (function () {
/**
* @param priorityFunc - A function that takes the a value that
* has previously been inserted, and returns a priority.
*
* A lower score is higher priority.
*
* Ex. (monster) => monster.speed
*/
function HeapPriorityQueue(priorityFunc) {
this.heap = [];
this.priorityFunc = priorityFunc;
}
HeapPriorityQueue.prototype.getPriority = function (t) {
return this.priorityFunc(t);
};
HeapPriorityQueue.prototype.findParent = function (index) {
if (index % 2) {
return (index - 1) / 2;
}
else {
return Math.ceil((index - 1) / 2);
}
};
HeapPriorityQueue.prototype.getChildFunction = function (parentIdx) {
var _a = [2 * parentIdx + 1, 2 * parentIdx + 2], left = _a[0], right = _a[1];
if (left >= this.heap.length - 1) {
// cannot go out of bounds for the array.
return Infinity;
}
if (this.getPriority(this.heap[left]) < this.getPriority(this.heap[right])) {
return left;
}
else {
return right;
}
};
HeapPriorityQueue.prototype.bubbleUpwards = function () {
var currentNodeIdx = this.heap.length - 1;
var currentNodeParentIdx = this.findParent(currentNodeIdx);
var newNode = this.heap[currentNodeIdx];
while (this.getPriority(newNode) <
this.getPriority(this.heap[currentNodeParentIdx])) {
var parent_1 = this.heap[currentNodeParentIdx];
this.heap[currentNodeParentIdx] = newNode;
this.heap[currentNodeIdx] = parent_1;
currentNodeIdx = currentNodeParentIdx;
currentNodeParentIdx = Math.floor(currentNodeIdx / 2);
}
};
HeapPriorityQueue.prototype.bubbleDownwards = function () {
var _this = this;
// Special case for smaller sizes
if (this.size() < 3) {
this.heap.sort(function (a, b) { return _this.getPriority(a) - _this.getPriority(b); });
return;
}
var currentIdx = 0;
var currentChildIdx = this.getChildFunction(currentIdx);
while (this.getPriority(this.heap[currentIdx]) >
this.getPriority(this.heap[currentChildIdx])) {
var futureIdx = currentChildIdx; // this will become the new parent node at the end.
var currentNode = this.heap[currentIdx]; // grabs the node.
var futureNode = this.heap[currentChildIdx]; // grabs the child node.
this.heap[currentChildIdx] = currentNode; // swaps node
this.heap[currentIdx] = futureNode; // swaps node
currentIdx = futureIdx; // sets the current node from the child
currentChildIdx = this.getChildFunction(currentIdx); // gets children.
if (currentChildIdx === Infinity) {
break;
}
}
};
/**
* Insert data into the queue
* @param data - The data to insert
*/
HeapPriorityQueue.prototype.insert = function (data) {
this.heap.push(data);
this.bubbleUpwards();
};
/**
* Get the item with the lowest priority score,
* removing it from the queue.
* @returns - The lowest priority item
*/
HeapPriorityQueue.prototype.pop = function () {
var toRemove = this.heap.shift();
this.bubbleDownwards();
return toRemove;
};
/**
* Get the item with the lowest priotity score,
* WITHOUT removing it.
* @returns - The lowest priority item
*/
HeapPriorityQueue.prototype.peek = function () {
return this.heap[0];
};
/**
* Returns the number of items in the queue.
* @returns - Number of items in the queue.
*/
HeapPriorityQueue.prototype.size = function () {
return this.heap.length;
};
return HeapPriorityQueue;
}());
exports.HeapPriorityQueue = HeapPriorityQueue;
//# sourceMappingURL=priority-queue-heap.js.map