113 lines
3.6 KiB
JavaScript
113 lines
3.6 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
/**
|
|
* @param container
|
|
* @param cmp default cmp will generate a max heap
|
|
* @constructor
|
|
*/
|
|
function PriorityQueue(container, cmp) {
|
|
if (container === void 0) { container = []; }
|
|
cmp = cmp || (function (x, y) {
|
|
if (x > y)
|
|
return -1;
|
|
if (x < y)
|
|
return 1;
|
|
return 0;
|
|
});
|
|
var priorityQueue = [];
|
|
container.forEach(function (element) { return priorityQueue.push(element); });
|
|
var len = priorityQueue.length;
|
|
var swap = function (x, y) {
|
|
if (x < 0 || x >= len)
|
|
throw new Error("unknown error");
|
|
if (y < 0 || y >= len)
|
|
throw new Error("unknown error");
|
|
var tmp = priorityQueue[x];
|
|
priorityQueue[x] = priorityQueue[y];
|
|
priorityQueue[y] = tmp;
|
|
};
|
|
var adjust = function (parent) {
|
|
if (parent < 0 || parent >= len)
|
|
throw new Error("unknown error");
|
|
var leftChild = parent * 2 + 1;
|
|
var rightChild = parent * 2 + 2;
|
|
if (leftChild < len && cmp(priorityQueue[parent], priorityQueue[leftChild]) > 0)
|
|
swap(parent, leftChild);
|
|
if (rightChild < len && cmp(priorityQueue[parent], priorityQueue[rightChild]) > 0)
|
|
swap(parent, rightChild);
|
|
};
|
|
(function () {
|
|
for (var parent_1 = Math.floor((len - 1) / 2); parent_1 >= 0; --parent_1) {
|
|
var curParent = parent_1;
|
|
var curChild = curParent * 2 + 1;
|
|
while (curChild < len) {
|
|
var leftChild = curChild;
|
|
var rightChild = leftChild + 1;
|
|
var minChild = leftChild;
|
|
if (rightChild < len && cmp(priorityQueue[leftChild], priorityQueue[rightChild]) > 0)
|
|
minChild = rightChild;
|
|
if (cmp(priorityQueue[curParent], priorityQueue[minChild]) <= 0)
|
|
break;
|
|
swap(curParent, minChild);
|
|
curParent = minChild;
|
|
curChild = curParent * 2 + 1;
|
|
}
|
|
}
|
|
})();
|
|
this.size = function () {
|
|
return len;
|
|
};
|
|
this.empty = function () {
|
|
return len === 0;
|
|
};
|
|
this.clear = function () {
|
|
len = 0;
|
|
priorityQueue.length = 0;
|
|
};
|
|
this.push = function (element) {
|
|
priorityQueue.push(element);
|
|
++len;
|
|
if (len === 1)
|
|
return;
|
|
var curNode = len - 1;
|
|
while (curNode > 0) {
|
|
var parent_2 = Math.floor((curNode - 1) / 2);
|
|
if (cmp(priorityQueue[parent_2], element) <= 0)
|
|
break;
|
|
adjust(parent_2);
|
|
curNode = parent_2;
|
|
}
|
|
};
|
|
this.pop = function () {
|
|
if (this.empty())
|
|
return;
|
|
if (this.size() === 1) {
|
|
--len;
|
|
return;
|
|
}
|
|
var last = priorityQueue[len - 1];
|
|
--len;
|
|
var parent = 0;
|
|
while (parent < this.size()) {
|
|
var leftChild = parent * 2 + 1;
|
|
var rightChild = parent * 2 + 2;
|
|
if (leftChild >= this.size())
|
|
break;
|
|
var minChild = leftChild;
|
|
if (rightChild < this.size() && cmp(priorityQueue[leftChild], priorityQueue[rightChild]) > 0)
|
|
minChild = rightChild;
|
|
if (cmp(priorityQueue[minChild], last) >= 0)
|
|
break;
|
|
priorityQueue[parent] = priorityQueue[minChild];
|
|
parent = minChild;
|
|
}
|
|
priorityQueue[parent] = last;
|
|
};
|
|
this.top = function () {
|
|
return priorityQueue[0];
|
|
};
|
|
Object.freeze(this);
|
|
}
|
|
Object.freeze(PriorityQueue);
|
|
exports.default = PriorityQueue;
|