@js-sdsl/priority-queue
Version:
javascript standard data structure library which benchmark against C++ STL
322 lines (311 loc) • 10.8 kB
JavaScript
/*!
* @js-sdsl/priority-queue v4.4.0
* https://github.com/js-sdsl/js-sdsl
* (c) 2021-present ZLY201 <zilongyao1366@gmail.com>
* MIT license
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.sdsl = {}));
})(this, (function (exports) { 'use strict';
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf || {
__proto__: []
} instanceof Array && function (d, b) {
d.__proto__ = b;
} || function (d, b) {
for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];
};
return extendStatics(d, b);
};
function __extends(d, b) {
if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() {
this.constructor = d;
}
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
function __read(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o),
r,
ar = [],
e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
} catch (error) {
e = {
error: error
};
} finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
} finally {
if (e) throw e.error;
}
}
return ar;
}
function __spreadArray(to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
}
var Base = /** @class */function () {
function Base() {
/**
* @description Container's size.
* @internal
*/
this._length = 0;
}
Object.defineProperty(Base.prototype, "length", {
/**
* @returns The size of the container.
* @example
* const container = new Vector([1, 2]);
* console.log(container.length); // 2
*/
get: function () {
return this._length;
},
enumerable: false,
configurable: true
});
/**
* @returns The size of the container.
* @example
* const container = new Vector([1, 2]);
* console.log(container.size()); // 2
*/
Base.prototype.size = function () {
return this._length;
};
/**
* @returns Whether the container is empty.
* @example
* container.clear();
* console.log(container.empty()); // true
*/
Base.prototype.empty = function () {
return this._length === 0;
};
return Base;
}();
/** @class */(function (_super) {
__extends(Container, _super);
function Container() {
return _super !== null && _super.apply(this, arguments) || this;
}
return Container;
})(Base);
var PriorityQueue = /** @class */function (_super) {
__extends(PriorityQueue, _super);
/**
* @description PriorityQueue's constructor.
* @param container - Initialize container, must have a forEach function.
* @param cmp - Compare function.
* @param copy - When the container is an array, you can choose to directly operate on the original object of
* the array or perform a shallow copy. The default is shallow copy.
* @example
* new PriorityQueue();
* new PriorityQueue([1, 2, 3]);
* new PriorityQueue([1, 2, 3], (x, y) => x - y);
* new PriorityQueue([1, 2, 3], (x, y) => x - y, false);
*/
function PriorityQueue(container, cmp, copy) {
if (container === void 0) {
container = [];
}
if (cmp === void 0) {
cmp = function (x, y) {
if (x > y) return -1;
if (x < y) return 1;
return 0;
};
}
if (copy === void 0) {
copy = true;
}
var _this = _super.call(this) || this;
_this._cmp = cmp;
if (Array.isArray(container)) {
_this._priorityQueue = copy ? __spreadArray([], __read(container), false) : container;
} else {
_this._priorityQueue = [];
var self_1 = _this;
container.forEach(function (el) {
self_1._priorityQueue.push(el);
});
}
_this._length = _this._priorityQueue.length;
var halfLength = _this._length >> 1;
for (var parent_1 = _this._length - 1 >> 1; parent_1 >= 0; --parent_1) {
_this._pushDown(parent_1, halfLength);
}
return _this;
}
/**
* @internal
*/
PriorityQueue.prototype._pushUp = function (pos) {
var item = this._priorityQueue[pos];
while (pos > 0) {
var parent_2 = pos - 1 >> 1;
var parentItem = this._priorityQueue[parent_2];
if (this._cmp(parentItem, item) <= 0) break;
this._priorityQueue[pos] = parentItem;
pos = parent_2;
}
this._priorityQueue[pos] = item;
};
/**
* @internal
*/
PriorityQueue.prototype._pushDown = function (pos, halfLength) {
var item = this._priorityQueue[pos];
while (pos < halfLength) {
var left = pos << 1 | 1;
var right = left + 1;
var minItem = this._priorityQueue[left];
if (right < this._length && this._cmp(minItem, this._priorityQueue[right]) > 0) {
left = right;
minItem = this._priorityQueue[right];
}
if (this._cmp(minItem, item) >= 0) break;
this._priorityQueue[pos] = minItem;
pos = left;
}
this._priorityQueue[pos] = item;
};
PriorityQueue.prototype.clear = function () {
this._length = 0;
this._priorityQueue.length = 0;
};
/**
* @description Push element into a container in order.
* @param item - The element you want to push.
* @returns The size of heap after pushing.
* @example
* queue.push(1);
*/
PriorityQueue.prototype.push = function (item) {
this._priorityQueue.push(item);
this._pushUp(this._length);
this._length += 1;
};
/**
* @description Removes the top element.
* @returns The element you popped.
* @example
* queue.pop();
*/
PriorityQueue.prototype.pop = function () {
if (this._length === 0) return;
var value = this._priorityQueue[0];
var last = this._priorityQueue.pop();
this._length -= 1;
if (this._length) {
this._priorityQueue[0] = last;
this._pushDown(0, this._length >> 1);
}
return value;
};
/**
* @description Accesses the top element.
* @example
* const top = queue.top();
*/
PriorityQueue.prototype.top = function () {
return this._priorityQueue[0];
};
/**
* @description Check if element is in heap.
* @param item - The item want to find.
* @returns Whether element is in heap.
* @example
* const que = new PriorityQueue([], (x, y) => x.id - y.id);
* const obj = { id: 1 };
* que.push(obj);
* console.log(que.find(obj)); // true
*/
PriorityQueue.prototype.find = function (item) {
return this._priorityQueue.indexOf(item) >= 0;
};
/**
* @description Remove specified item from heap.
* @param item - The item want to remove.
* @returns Whether remove success.
* @example
* const que = new PriorityQueue([], (x, y) => x.id - y.id);
* const obj = { id: 1 };
* que.push(obj);
* que.remove(obj);
*/
PriorityQueue.prototype.remove = function (item) {
var index = this._priorityQueue.indexOf(item);
if (index < 0) return false;
if (index === 0) {
this.pop();
} else if (index === this._length - 1) {
this._priorityQueue.pop();
this._length -= 1;
} else {
this._priorityQueue.splice(index, 1, this._priorityQueue.pop());
this._length -= 1;
this._pushUp(index);
this._pushDown(index, this._length >> 1);
}
return true;
};
/**
* @description Update item and it's pos in the heap.
* @param item - The item want to update.
* @returns Whether update success.
* @example
* const que = new PriorityQueue([], (x, y) => x.id - y.id);
* const obj = { id: 1 };
* que.push(obj);
* obj.id = 2;
* que.updateItem(obj);
*/
PriorityQueue.prototype.updateItem = function (item) {
var index = this._priorityQueue.indexOf(item);
if (index < 0) return false;
this._pushUp(index);
this._pushDown(index, this._length >> 1);
return true;
};
/**
* @returns Return a copy array of heap.
* @example
* const arr = queue.toArray();
*/
PriorityQueue.prototype.toArray = function () {
return __spreadArray([], __read(this._priorityQueue), false);
};
return PriorityQueue;
}(Base);
exports.PriorityQueue = PriorityQueue;
Object.defineProperty(exports, '__esModule', { value: true });
}));