12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- export default class TinyQueue {
- constructor(data = [], compare = defaultCompare) {
- this.data = data;
- this.length = this.data.length;
- this.compare = compare;
- if (this.length > 0) {
- for (let i = (this.length >> 1) - 1; i >= 0; i--) this._down(i);
- }
- }
- push(item) {
- this.data.push(item);
- this.length++;
- this._up(this.length - 1);
- }
- pop() {
- if (this.length === 0) return undefined;
- const top = this.data[0];
- const bottom = this.data.pop();
- this.length--;
- if (this.length > 0) {
- this.data[0] = bottom;
- this._down(0);
- }
- return top;
- }
- peek() {
- return this.data[0];
- }
- _up(pos) {
- const {data, compare} = this;
- const item = data[pos];
- while (pos > 0) {
- const parent = (pos - 1) >> 1;
- const current = data[parent];
- if (compare(item, current) >= 0) break;
- data[pos] = current;
- pos = parent;
- }
- data[pos] = item;
- }
- _down(pos) {
- const {data, compare} = this;
- const halfLength = this.length >> 1;
- const item = data[pos];
- while (pos < halfLength) {
- let left = (pos << 1) + 1;
- let best = data[left];
- const right = left + 1;
- if (right < this.length && compare(data[right], best) < 0) {
- left = right;
- best = data[right];
- }
- if (compare(best, item) >= 0) break;
- data[pos] = best;
- pos = left;
- }
- data[pos] = item;
- }
- }
- function defaultCompare(a, b) {
- return a < b ? -1 : a > b ? 1 : 0;
- }
|