1 Array.prototype.swap = function(i, j)
9 function Heap(maxSize, compare)
11 this._maxSize = maxSize;
12 this._compare = compare;
14 this._values = new Array(this._maxSize);
19 // This is a binary heap represented in an array. The root element is stored
20 // in the first element in the array. The root is followed by its two children.
21 // Then its four grandchildren and so on. So every level in the binary heap is
22 // doubled in the following level. Here is an example of the node indices and
23 // how they are related to their parents and children.
24 // ===========================================================================
26 // PARENT -1 0 0 1 1 2 2
27 // LEFT 1 3 5 7 9 11 13
28 // RIGHT 2 4 6 8 10 12 14
29 // ===========================================================================
30 _parentIndex: function(i)
32 return i > 0 ? Math.floor((i - 1) / 2) : -1;
35 _leftIndex: function(i)
37 var leftIndex = i * 2 + 1;
38 return leftIndex < this._size ? leftIndex : -1;
41 _rightIndex: function(i)
43 var rightIndex = i * 2 + 2;
44 return rightIndex < this._size ? rightIndex : -1;
47 // Return the child index that may violate the heap property at index i.
48 _childIndex: function(i)
50 var left = this._leftIndex(i);
51 var right = this._rightIndex(i);
53 if (left != -1 && right != -1)
54 return this._compare(this._values[left], this._values[right]) > 0 ? left : right;
56 return left != -1 ? left : right;
66 return this._size ? this._values[0] : NaN;
71 if (this._size == this._maxSize) {
72 // If size is bounded and the new value can be a parent of the top()
73 // if the size were unbounded, just ignore the new value.
74 if (this._compare(value, this.top()) > 0)
78 this._values[this._size++] = value;
79 this._bubble(this._size - 1);
87 this._values[0] = this._values[--this._size];
93 // Fix the heap property at index i given that parent is the only node that
94 // may violate the heap property.
95 for (var pi = this._parentIndex(i); pi != -1; i = pi, pi = this._parentIndex(pi)) {
96 if (this._compare(this._values[pi], this._values[i]) > 0)
99 this._values.swap(pi, i);
105 // Fix the heap property at index i given that each of the left and the right
106 // sub-trees satisfies the heap property.
107 for (var ci = this._childIndex(i); ci != -1; i = ci, ci = this._childIndex(ci)) {
108 if (this._compare(this._values[i], this._values[ci]) > 0)
111 this._values.swap(ci, i);
117 var out = "Heap[" + this._size + "] = [";
118 for (var i = 0; i < this._size; ++i) {
119 out += this._values[i];
120 if (i < this._size - 1)
126 values: function(size) {
127 // Return the last "size" heap elements values.
128 var values = this._values.slice(0, this._size);
129 return values.sort(this._compare).slice(0, Math.min(size, this._size));
134 createMinHeap: function(maxSize)
136 return new Heap(maxSize, function(a, b) { return b - a; });
139 createMaxHeap: function(maxSize) {
140 return new Heap(maxSize, function(a, b) { return a - b; });