hashes
Version:
A package implementing a HashTable and HashSet
201 lines (185 loc) • 4.8 kB
JavaScript
/**
* @fileOverview Implementation of a min heap. Allows a comparator
* to be provided so that the heap may contain objects that involve a
* more complex comparison.
*/
/**
* Implementation of a min heap allowing for a comparator
* to be provided so that the heap may contain objects that involve a
* more complex comparison.
* <br>
* This constructor constructs a MinHeap instance and takes two optional
* parameters: an array and comparator. If the array is provided, it
* will be used as the backing store for the heap. Therefore, all
* operations on the heap will be reflected in the provided array.
* Usage
* @example
* Sample Usage:
var heapq = new MinHeap();
heapq.push(5);
heapq.push(2);
heapq.push(1);
heapq.pop()); // returns 1
heapq.pop()); // returns 2
* @param array Array to use heapify or null to start with an empty
* heap.
* @param comparator alternate comparator used to compare each
* item within the heap. If not provided, the default will perform
* a simple comparison on the item.
*
* @returns instance of MinHeap
* @constructor
*/
function MinHeap(array, comparator) {
/**
* Storage for heap.
* @private
*/
this.heap = array || new Array();
/**
* Default comparator used if an override is not provided.
* @private
*/
this.compare = comparator || function(item1, item2) {
return item1 == item2 ? 0 : item1 < item2 ? -1 : 1;
};
/**
* Retrieve the index of the left child of the node at index i.
* @private
*/
this.left = function(i) {
return 2 * i + 1;
};
/**
* Retrieve the index of the right child of the node at index i.
* @private
*/
this.right = function(i) {
return 2 * i + 2;
};
/**
* Retrieve the index of the parent of the node at index i.
* @private
*/
this.parent = function(i) {
return Math.ceil(i / 2) - 1;
};
/**
* Ensure that the contents of the heap don't violate the
* constraint.
* @private
*/
this.heapify = function(i) {
var lIdx = this.left(i);
var rIdx = this.right(i);
var smallest;
if (lIdx < this.heap.length
&& this.compare(this.heap[lIdx], this.heap[i]) < 0) {
smallest = lIdx;
} else {
smallest = i;
}
if (rIdx < this.heap.length
&& this.compare(this.heap[rIdx], this.heap[smallest]) < 0) {
smallest = rIdx;
}
if (i != smallest) {
var temp = this.heap[smallest];
this.heap[smallest] = this.heap[i];
this.heap[i] = temp;
this.heapify(smallest);
}
};
/**
* Starting with the node at index i, move up the heap until parent value
* is less than the node.
* @private
*/
this.siftUp = function(i) {
var p = this.parent(i);
if (p >= 0 && this.compare(this.heap[p], this.heap[i]) > 0) {
var temp = this.heap[p];
this.heap[p] = this.heap[i];
this.heap[i] = temp;
this.siftUp(p);
}
};
/**
* Heapify the contents of an array.
* This function is called when an array is provided.
* @private
*/
this.heapifyArray = function() {
// for loop starting from floor size/2 going up and heapify each.
var i = Math.floor(this.heap.length / 2) - 1;
for (; i >= 0; i--) {
// jstestdriver.console.log("i: ", i);
this.heapify(i);
}
};
// If an initial array was provided, then heapify the array.
if (array != null) {
this.heapifyArray();
}
;
}
/**
* Place an item in the heap.
* @param item
* @function
*/
MinHeap.prototype.push = function(item) {
this.heap.push(item);
this.siftUp(this.heap.length - 1);
};
/**
* Insert an item into the heap.
* @param item
* @function
*/
MinHeap.prototype.insert = function(item) {
this.push(item);
};
/**
* Pop the minimum valued item off of the heap. The heap is then updated
* to float the next smallest item to the top of the heap.
* @returns the minimum value contained within the heap.
* @function
*/
MinHeap.prototype.pop = function() {
var value;
if (this.heap.length > 1) {
value = this.heap[0];
// Put the bottom element at the top and let it drift down.
this.heap[0] = this.heap.pop();
this.heapify(0);
} else {
value = this.heap.pop();
}
return value;
};
/**
* Remove the minimum item from the heap.
* @returns the minimum value contained within the heap.
* @function
*/
MinHeap.prototype.remove = function() {
return this.pop();
};
/**
* Returns the minimum value contained within the heap. This will
* not remove the value from the heap.
* @returns the minimum value within the heap.
* @function
*/
MinHeap.prototype.getMin = function() {
return this.heap[0];
};
/**
* Return the current number of elements within the heap.
* @returns size of the heap.
* @function
*/
MinHeap.prototype.size = function() {
return this.heap.length;
};