1 line
10 KiB
Plaintext
1 line
10 KiB
Plaintext
{"version":3,"sources":["binary-heap/max-heap.js","binary-heap/min-heap.js","binary-heap/min-max-heap.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,sB;AACA,6D;AACA,a;AACA,kE;AACA,iB;AACA,iD;AACA,0C;AACA,8B;AACA,6E;AACA,gE;AACA,0C;AACA,iC;AACA,qF;AACA,kB;;AAEA,wE;AACA,gF;AACA,gE;AACA,gC;;AAEA,wD;;AAEA,8E;AACA,mB;AACA,oC;;AAEA,4E;AACA,gF;AACA,+E;AACA,0C;AACA,kB;;AAEA,yE;AACA,6E;AACA,iC;AACA,kC;AACA,yC;AACA,E;;AAEA,6B;AACA,mE;AACA,kC;AACA,oB;;AAEA,2C;AACA,0C;AACA,O;;AAEA,kC;AACA,iC;AACA,O;;AAEA,sB;AACA,a;;AAEA,kE;AACA,yD;AACA,wB;AACA,I;;AAEA,6B;AACA,oB;;AAEA,6C;AACA,mC;AACA,qC;AACA,wB;;AAEA,+B;AACA,gD;AACA,O;AACA,gC;AACA,iD;AACA,O;;AAEA,0B;AACA,c;;AAEA,+B;AACA,oB;AACA,K;AACA,I;;AAEA,2B;AACA,oB;;AAEA,qB;AACA,kC;AACA,gD;AACA,+B;AACA,qB;AACA,c;AACA,c;AACA,O;AACA,K;AACA,I;;AAEA,oC;AACA,oB;AACA,iC;AACA,iC;AACA,+D;AACA,I;;AAEA,iE;AACA,wB;AACA,oB;AACA,iC;AACA,I;;AAEA,gC;AACA,oB;AACA,gC;AACA,gC;;AAEA,qC;AACA,qC;;AAEA,4B;AACA,4B;AACA,I;;AAEA,sB;AACA,oB;AACA,uB;AACA,kB;AACA,4C;AACA,I;AACA,6B;AACA,oB;;AAEA,uB;AACA,iC;AACA,e;;AAEA,sC;AACA,oC;;AAEA,qC;AACA,oE;AACA,wB;AACA,oE;AACA,0B;AACA,Y;AACA,+C;AACA,gD;AACA,0C;AACA,K;AACA,I;AACA,yB;AACA,oB;;AAEA,uB;AACA,uC;AACA,sC;;AAEA,yB;AACA,8B;AACA,yB;AACA,iC;;AAEA,2C;AACA,0B;AACA,4B;AACA,c;AACA,yB;AACA,iC;AACA,O;AACA,K;AACA,I;AACA,sB;AACA,oB;AACA,iC;AACA,I;AACA,sB;AACA,oB;AACA,wB;AACA,I;AACA,sB;AACA,oB;AACA,oB;AACA,0B;AACA,I;AACA,+C;AACA,gC;AACA,oB;AACA,uC;AACA,yC;AACA,O;AACA,I;AACA,qB;AACA,oB;AACA,6B;AACA,I;AACA,kC;AACA,oB;AACA,qB;AACA,0B;AACA,sB;AACA,e;AACA,I;AACA,sB;AACA,oB;AACA,0D;AACA,iB;AACA,I;;AAEA,6B;AACA,oB;AACA,iD;AACA,I;;AAEA,2B;AACA,oB;AACA,+C;AACA,2D;AACA,iE;AACA,6D;AACA,uD;AACA,G;AACA,G;;AAEA,+C;AACA,gD;AACA,+C;;;;;;;;;;;;;;;;;;;;AChOA,0C;AACA,kB;AACA,sC;AACA,6B;AACA,c;AACA,E;;AAEA,mC;;AAEA,6B;AACA,6B;AACA,2D;AACA,I;AACA,6B;AACA,oB;AACA,qD;AACA,G;AACA,G;;;;;;;;;;;;;;;;;;;;ACjBA,qE;AACA,+C;AACA,E;AACA,gF;AACA,S;AACA,E;AACA,yE;AACA,0E;AACA,+D;AACA,gF;AACA,qB;AACA,+D;AACA,6C;AACA,kB;;AAEA,0C;AACA,mD;AACA,E;;AAEA,sC;;AAEA,gC;AACA,6B;AACA,oB;AACA,iD;AACA,iC;AACA,I;AACA,yB;AACA,oB;AACA,oD;AACA,6B;AACA,I;AACA,sB;AACA,oB;AACA,mD;AACA,0B;AACA,I;AACA,kC;AACA,oB;AACA,wD;AACA,6C;AACA,I;AACA,sB;AACA,oB;AACA,6D;AACA,iB;AACA,I;AACA,6B;AACA,oB;AACA,wC;AACA,G;AACA,G","file":"/packages/binary-heap.js","sourcesContent":["// Constructor of Heap\n// - comparator - Function - given two items returns a number\n// - options:\n// - initData - Array - Optional - the initial data in a format:\n// Object:\n// - id - String - unique id of the item\n// - value - Any - the data value\n// each value is retained\n// - IdMap - Constructor - Optional - custom IdMap class to store id->index\n// mappings internally. Standard IdMap is used by default.\nMaxHeap = function (comparator, options) {\n if (! _.isFunction(comparator))\n throw new Error('Passed comparator is invalid, should be a comparison function');\n var self = this;\n\n // a C-style comparator that is given two values and returns a number,\n // negative if the first value is less than the second, positive if the second\n // value is greater than the first and zero if they are equal.\n self._comparator = comparator;\n\n options = _.defaults(options || {}, { IdMap: IdMap });\n\n // _heapIdx maps an id to an index in the Heap array the corresponding value\n // is located on.\n self._heapIdx = new options.IdMap;\n\n // The Heap data-structure implemented as a 0-based contiguous array where\n // every item on index idx is a node in a complete binary tree. Every node can\n // have children on indexes idx*2+1 and idx*2+2, except for the leaves. Every\n // node has a parent on index (idx-1)/2;\n self._heap = [];\n\n // If the initial array is passed, we can build the heap in linear time\n // complexity (O(N)) compared to linearithmic time complexity (O(nlogn)) if\n // we push elements one by one.\n if (_.isArray(options.initData))\n self._initFromData(options.initData);\n};\n\n_.extend(MaxHeap.prototype, {\n // Builds a new heap in-place in linear time based on passed data\n _initFromData: function (data) {\n var self = this;\n\n self._heap = _.map(data, function (o) {\n return { id: o.id, value: o.value };\n });\n\n _.each(data, function (o, i) {\n self._heapIdx.set(o.id, i);\n });\n\n if (! data.length)\n return;\n\n // start from the first non-leaf - the parent of the last leaf\n for (var i = parentIdx(data.length - 1); i >= 0; i--)\n self._downHeap(i);\n },\n\n _downHeap: function (idx) {\n var self = this;\n\n while (leftChildIdx(idx) < self.size()) {\n var left = leftChildIdx(idx);\n var right = rightChildIdx(idx);\n var largest = idx;\n\n if (left < self.size()) {\n largest = self._maxIndex(largest, left);\n }\n if (right < self.size()) {\n largest = self._maxIndex(largest, right);\n }\n\n if (largest === idx)\n break;\n\n self._swap(largest, idx);\n idx = largest;\n }\n },\n\n _upHeap: function (idx) {\n var self = this;\n\n while (idx > 0) {\n var parent = parentIdx(idx);\n if (self._maxIndex(parent, idx) === idx) {\n self._swap(parent, idx)\n idx = parent;\n } else {\n break;\n }\n }\n },\n\n _maxIndex: function (idxA, idxB) {\n var self = this;\n var valueA = self._get(idxA);\n var valueB = self._get(idxB);\n return self._comparator(valueA, valueB) >= 0 ? idxA : idxB;\n },\n\n // Internal: gets raw data object placed on idxth place in heap\n _get: function (idx) {\n var self = this;\n return self._heap[idx].value;\n },\n\n _swap: function (idxA, idxB) {\n var self = this;\n var recA = self._heap[idxA];\n var recB = self._heap[idxB];\n\n self._heapIdx.set(recA.id, idxB);\n self._heapIdx.set(recB.id, idxA);\n\n self._heap[idxA] = recB;\n self._heap[idxB] = recA;\n },\n\n get: function (id) {\n var self = this;\n if (! self.has(id))\n return null;\n return self._get(self._heapIdx.get(id));\n },\n set: function (id, value) {\n var self = this;\n\n if (self.has(id)) {\n if (self.get(id) === value)\n return;\n\n var idx = self._heapIdx.get(id);\n self._heap[idx].value = value;\n\n // Fix the new value's position\n // Either bubble new value up if it is greater than its parent\n self._upHeap(idx);\n // or bubble it down if it is smaller than one of its children\n self._downHeap(idx);\n } else {\n self._heapIdx.set(id, self._heap.length);\n self._heap.push({ id: id, value: value });\n self._upHeap(self._heap.length - 1);\n }\n },\n remove: function (id) {\n var self = this;\n\n if (self.has(id)) {\n var last = self._heap.length - 1;\n var idx = self._heapIdx.get(id);\n\n if (idx !== last) {\n self._swap(idx, last);\n self._heap.pop();\n self._heapIdx.remove(id);\n\n // Fix the swapped value's position\n self._upHeap(idx);\n self._downHeap(idx);\n } else {\n self._heap.pop();\n self._heapIdx.remove(id);\n }\n }\n },\n has: function (id) {\n var self = this;\n return self._heapIdx.has(id);\n },\n empty: function () {\n var self = this;\n return !self.size();\n },\n clear: function () {\n var self = this;\n self._heap = [];\n self._heapIdx.clear();\n },\n // iterate over values in no particular order\n forEach: function (iterator) {\n var self = this;\n _.each(self._heap, function (obj) {\n return iterator(obj.value, obj.id);\n });\n },\n size: function () {\n var self = this;\n return self._heap.length;\n },\n setDefault: function (id, def) {\n var self = this;\n if (self.has(id))\n return self.get(id);\n self.set(id, def);\n return def;\n },\n clone: function () {\n var self = this;\n var clone = new MaxHeap(self._comparator, self._heap);\n return clone;\n },\n\n maxElementId: function () {\n var self = this;\n return self.size() ? self._heap[0].id : null;\n },\n\n _selfCheck: function () {\n var self = this;\n for (var i = 1; i < self._heap.length; i++)\n if (self._maxIndex(parentIdx(i), i) !== parentIdx(i))\n throw new Error(\"An item with id \" + self._heap[i].id +\n \" has a parent younger than it: \" +\n self._heap[parentIdx(i)].id);\n }\n});\n\nfunction leftChildIdx (i) { return i * 2 + 1; }\nfunction rightChildIdx (i) { return i * 2 + 2; }\nfunction parentIdx (i) { return (i - 1) >> 1; }\n\n","MinHeap = function (comparator, options) {\n var self = this;\n MaxHeap.call(self, function (a, b) {\n return -comparator(a, b);\n }, options);\n};\n\nMeteor._inherits(MinHeap, MaxHeap);\n\n_.extend(MinHeap.prototype, {\n maxElementId: function () {\n throw new Error(\"Cannot call maxElementId on MinHeap\");\n },\n minElementId: function () {\n var self = this;\n return MaxHeap.prototype.maxElementId.call(self);\n }\n});\n\n","// This implementation of Min/Max-Heap is just a subclass of Max-Heap\n// with a Min-Heap as an encapsulated property.\n//\n// Most of the operations are just proxy methods to call the same method on both\n// heaps.\n//\n// This implementation takes 2*N memory but is fairly simple to write and\n// understand. And the constant factor of a simple Heap is usually smaller\n// compared to other two-way priority queues like Min/Max Heaps\n// (http://www.cs.otago.ac.nz/staffpriv/mike/Papers/MinMaxHeaps/MinMaxHeaps.pdf)\n// and Interval Heaps\n// (http://www.cise.ufl.edu/~sahni/dsaac/enrich/c13/double.htm)\nMinMaxHeap = function (comparator, options) {\n var self = this;\n\n MaxHeap.call(self, comparator, options);\n self._minHeap = new MinHeap(comparator, options);\n};\n\nMeteor._inherits(MinMaxHeap, MaxHeap);\n\n_.extend(MinMaxHeap.prototype, {\n set: function (id, value) {\n var self = this;\n MaxHeap.prototype.set.apply(self, arguments);\n self._minHeap.set(id, value);\n },\n remove: function (id) {\n var self = this;\n MaxHeap.prototype.remove.apply(self, arguments);\n self._minHeap.remove(id);\n },\n clear: function () {\n var self = this;\n MaxHeap.prototype.clear.apply(self, arguments);\n self._minHeap.clear();\n },\n setDefault: function (id, def) {\n var self = this;\n MaxHeap.prototype.setDefault.apply(self, arguments);\n return self._minHeap.setDefault(id, def);\n },\n clone: function () {\n var self = this;\n var clone = new MinMaxHeap(self._comparator, self._heap);\n return clone;\n },\n minElementId: function () {\n var self = this;\n return self._minHeap.minElementId();\n }\n});\n\n"]} |