@antv/x6
Version:
JavaScript diagramming library that uses SVG and HTML for rendering.
177 lines • 5.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PriorityQueue = void 0;
/**
* An implementation of the Priority Queue abstract data type.
*
* @see: http://en.wikipedia.org/wiki/Priority_queue
*
* It is like a normal stack or queue, but where each item has assigned a
* priority (a number). Items with higher priority are served before items
* with lower priority. This implementation uses binary heap as an internal
* representation of the queue. The time complexity of all the methods is as
* follows:
*
* - create: `O(n)`
* - insert: `O(log n)`
* - remove: `O(log n)`
* - peek: `O(1)`
* - isEmpty: `O(1)`
* - peekPriority: `O(1)`
*/
var PriorityQueue = /** @class */ (function () {
function PriorityQueue(options) {
if (options === void 0) { options = {}; }
this.comparator = options.comparator || PriorityQueue.defaultComparator;
this.index = {};
this.data = options.data || [];
this.heapify();
}
/**
* Returns `true` if the priority queue is empty, `false` otherwise.
*/
PriorityQueue.prototype.isEmpty = function () {
return this.data.length === 0;
};
/**
* Inserts a value with priority to the queue. Optionally pass a unique
* id of this item. Passing unique IDs for each item you insert allows
* you to use the `updatePriority()` operation.
* @param priority
* @param value
* @param id
*/
PriorityQueue.prototype.insert = function (priority, value, id) {
var item = { priority: priority, value: value };
var index = this.data.length - 1;
if (id) {
item.id = id;
this.index[id] = index;
}
this.data.push(item);
this.bubbleUp(index);
return this;
};
/**
* Returns the value of an item with the highest priority.
*/
PriorityQueue.prototype.peek = function () {
return this.data[0] ? this.data[0].value : null;
};
/**
* Returns the highest priority in the queue.
*/
PriorityQueue.prototype.peekPriority = function () {
return this.data[0] ? this.data[0].priority : null;
};
PriorityQueue.prototype.updatePriority = function (id, priority) {
var index = this.index[id];
if (typeof index === 'undefined') {
throw new Error("Node with id '" + id + "' was not found in the heap.");
}
var data = this.data;
var oldPriority = data[index].priority;
var comp = this.comparator(priority, oldPriority);
if (comp < 0) {
data[index].priority = priority;
this.bubbleUp(index);
}
else if (comp > 0) {
data[index].priority = priority;
this.bubbleDown(index);
}
};
/**
* Removes the item with the highest priority from the queue
*
* @returns The value of the removed item.
*/
PriorityQueue.prototype.remove = function () {
var data = this.data;
var peek = data[0];
var last = data.pop();
delete this.index[data.length];
if (data.length > 0) {
data[0] = last;
if (last.id) {
this.index[last.id] = 0;
}
this.bubbleDown(0);
}
return peek ? peek.value : null;
};
PriorityQueue.prototype.heapify = function () {
for (var i = 0; i < this.data.length; i += 1) {
this.bubbleUp(i);
}
};
PriorityQueue.prototype.bubbleUp = function (index) {
var data = this.data;
var tmp;
var parent;
var current = index;
while (current > 0) {
parent = (current - 1) >>> 1;
if (this.comparator(data[current].priority, data[parent].priority) < 0) {
tmp = data[parent];
data[parent] = data[current];
var id = data[current].id;
if (id != null) {
this.index[id] = parent;
}
data[current] = tmp;
id = data[current].id;
if (id != null) {
this.index[id] = current;
}
current = parent;
}
else {
break;
}
}
};
PriorityQueue.prototype.bubbleDown = function (index) {
var data = this.data;
var last = data.length - 1;
var current = index;
// eslint-disable-next-line
while (true) {
var left = (current << 1) + 1;
var right = left + 1;
var minIndex = current;
if (left <= last &&
this.comparator(data[left].priority, data[minIndex].priority) < 0) {
minIndex = left;
}
if (right <= last &&
this.comparator(data[right].priority, data[minIndex].priority) < 0) {
minIndex = right;
}
if (minIndex !== current) {
var tmp = data[minIndex];
data[minIndex] = data[current];
var id = data[current].id;
if (id != null) {
this.index[id] = minIndex;
}
data[current] = tmp;
id = data[current].id;
if (id != null) {
this.index[id] = current;
}
current = minIndex;
}
else {
break;
}
}
};
return PriorityQueue;
}());
exports.PriorityQueue = PriorityQueue;
(function (PriorityQueue) {
PriorityQueue.defaultComparator = function (a, b) { return a - b; };
})(PriorityQueue = exports.PriorityQueue || (exports.PriorityQueue = {}));
exports.PriorityQueue = PriorityQueue;
//# sourceMappingURL=priorityqueue.js.map