nowjs-core
Version:
NowCanDo Javascript Core [nowjs-core] is a library written by TypeScript code maintains under Apache 2.0 licence
155 lines (154 loc) • 4.06 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const index_1 = require("../linq/index");
const Collection_1 = require("./Collection");
const List_1 = require("./List");
class PriorityQueue {
constructor(comparator, enumerable) {
this.comparator = comparator;
this.arr = [];
this.isSorted = false;
if (enumerable && enumerable[Symbol.iterator]) {
for (const x of enumerable) {
this.enqueue(x);
}
}
}
isEmpty() {
return this.size === 0;
}
contains(item) {
return (this.arr.findIndex(xx => {
return xx === item;
}) >= 0);
}
get size() {
return this.arr.length;
}
clear() {
this.arr = [];
return true;
}
enqueue(...rest) {
if (rest instanceof Array) {
for (const xx of rest) {
this.add(xx);
}
return true;
}
else {
this.add(rest);
return true;
}
}
dequeue() {
if (this.size === 0)
return undefined;
this.isSorted = false;
const top = this.arr[0];
let length = this.size;
length--;
if (length > 0) {
this.arr[0] = this.arr[length];
this.down(0);
}
this.arr.pop();
return top;
}
peek() {
if (this.arr.length > 0)
return this.arr[0];
else
return null;
}
toArray() {
const array = [];
for (const xx of this) {
array.push(xx);
}
return array;
}
toCollection() {
return new Collection_1.Collection(this);
}
toList() {
return new List_1.List(this);
}
toSet() {
return new Set(this);
}
linq() {
return new index_1.Enumerable(this);
}
plinq() {
return new index_1.ParallelEnumerable(this);
}
[Symbol.iterator]() {
if (this.isSorted === false) {
this.halfUp();
this.isSorted = true;
}
return this.arr[Symbol.iterator]();
}
clone() {
return new PriorityQueue(this.comparator, this);
}
add(item) {
this.arr.push(item);
this.isSorted = false;
this.up(this.size - 1);
return true;
}
compare(a, b) {
const compare = this.comparator;
return compare(this.arr[a], this.arr[b]);
}
swap(a, b) {
const aux = this.arr[a];
this.arr[a] = this.arr[b];
this.arr[b] = aux;
}
up(pos, full = false) {
let posCurrent = pos;
while (posCurrent > 0) {
const posParent = full ? posCurrent - 1 : Math.floor((posCurrent - 1) / 2);
if (this.compare(posParent, posCurrent) <= 0)
break;
this.swap(posParent, posCurrent);
posCurrent = posParent;
}
}
halfUp() {
if (this.size < 2)
return;
let posCurrent = this.size - 1;
const half = Math.floor((posCurrent - 1) / 2);
while (posCurrent > half) {
const posParent = posCurrent - 1;
if (this.compare(posParent, posCurrent) <= 0)
break;
this.swap(posParent, posCurrent);
posCurrent = posParent;
}
}
down(pos) {
const compare = this.comparator;
const halfLength = this.size >> 1;
const item = this.arr[pos];
while (pos < halfLength) {
let left = (pos << 1) + 1;
const right = left + 1;
let best = this.arr[left];
if (right < this.size && compare(this.arr[right], best) < 0) {
left = right;
best = this.arr[right];
}
if (compare(best, item) >= 0)
break;
this.arr[pos] = best;
pos = left;
}
this.arr[pos] = item;
}
}
exports.PriorityQueue = PriorityQueue;