UNPKG

priority-queue-typescript

Version:

Priority queue data structure where you are able to set your own compare function.

178 lines (175 loc) 5.12 kB
Object.defineProperty(exports, '__esModule', { value: true }); var _computedKey; _computedKey = Symbol.iterator; class PriorityQueue { grow() { const oldCapacity = this._size; // Double size if small; else grow by 50% const newCapacity = oldCapacity + (oldCapacity < 64 ? oldCapacity + 2 : oldCapacity >> 1); if (!Number.isSafeInteger(newCapacity)) { throw new Error('capacity out of range'); } this._queue.length = newCapacity; } siftup(k, item) { if (this._comparator !== null) { this.siftupUsingComparator(k, item); } else { this.siftupComparable(k, item); } } /** * siftup of heap */ siftupUsingComparator(k, item) { while(k > 0){ // find the parent let parent = k - 1 >>> 1; let e = this._queue[parent]; // compare item with it parent, if item's priority less, break siftup and insert if (this._comparator(item, e) >= 0) { break; } // if item's priority more, make it's parent sink and proceed siftup this._queue[k] = e; k = parent; } // if k === 0, then we directly insert it this._queue[k] = item; } siftupComparable(k, item) { while(k > 0){ let parent = k - 1 >>> 1; let e = this._queue[parent]; if (item.toString().localeCompare(e.toString()) >= 0) { break; } this._queue[k] = e; k = parent; } this._queue[k] = item; } sink(k, item) { if (this._comparator !== null) { this.sinkUsingComparator(k, item); } else { this.sinkComparable(k, item); } } sinkUsingComparator(k, item) { let half = this._size >>> 1; while(k < half){ let child = (k << 1) + 1; let object = this._queue[child]; let right = child + 1; // compare left right child, assgn child the bigger one if (right < this._size && this._comparator(object, this._queue[right]) > 0) { object = this._queue[child = right]; } //compare item and child if bigger is item, break if (this._comparator(item, object) <= 0) { break; } this._queue[k] = object; k = child; } this._queue[k] = item; } sinkComparable(k, item) { let half = this._size >>> 1; while(k < half){ let child = (k << 1) + 1; let object = this._queue[child]; let right = child + 1; if (right < this._size && object.toString().localeCompare(this._queue[right].toString())) { object = this._queue[child = right]; } if (item.toString().localeCompare(object.toString()) <= 0) { break; } this._queue[k] = object; k = child; } this._queue[k] = item; } indexOf(item) { for(let i = 0; i < this._queue.length; i++){ if (this._queue[i] === item) { return i; } } return -1; } add(item) { let i = this._size; if (i >= this._queue.length) { this.grow(); } this._size = i + 1; if (i === 0) { this._queue[0] = item; } else { this.siftup(i, item); } return true; } poll() { if (this._size === 0) { return null; } let s = --this._size; let result = this._queue[0]; let x = this._queue[s]; this._queue.slice(s, 1); if (s !== 0) { this.sink(0, x); } return result; } peek() { return this._size === 0 ? null : this._queue[0]; } contains(item) { return this.indexOf(item) !== -1; } clear() { for (let item of this._queue){ item = null; } this._size = 0; } size() { return this._size; } empty() { return this._size === 0; } toArray() { return this._queue.filter((item)=>item); } toString() { return this.toArray().toString(); } [_computedKey]() { let i = 0; return { next: ()=>{ return { done: i == this._size, value: this._queue[i++] }; } }; } constructor(initialCapacity, comparator){ this._size = 0; const cap = initialCapacity != null ? initialCapacity : 11; const com = comparator != null ? comparator : null; if (cap < 1) { throw new Error('initial capacity must be greater than or equal to 1'); } this._queue = new Array(cap); this._comparator = com; } } exports.PriorityQueue = PriorityQueue; exports.default = PriorityQueue;