You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
79 lines
2.1 KiB
79 lines
2.1 KiB
var Class = require('./Class'); |
|
var swap = require('./swap'); |
|
var isSorted = require('./isSorted'); |
|
exports = Class({ |
|
initialize: function Heap() { |
|
var cmp = |
|
arguments.length > 0 && arguments[0] !== undefined |
|
? arguments[0] |
|
: isSorted.defComparator; |
|
this._cmp = cmp; |
|
this.clear(); |
|
}, |
|
clear: function() { |
|
this._data = []; |
|
this.size = 0; |
|
}, |
|
add: function(item) { |
|
this._data.push(item); |
|
this.size++; |
|
this._heapifyUp(this.size - 1); |
|
return this.size; |
|
}, |
|
poll: function() { |
|
var data = this._data; |
|
if (this.size > 0) { |
|
var item = data[0]; |
|
data[0] = data[this.size - 1]; |
|
this.size--; |
|
this._heapifyDown(0); |
|
return item; |
|
} |
|
}, |
|
peek: function() { |
|
if (this.size > 0) { |
|
return this._data[0]; |
|
} |
|
}, |
|
_heapifyUp: function(idx) { |
|
var data = this._data; |
|
var parent = parentIdx(idx); |
|
while (idx > 0 && this._cmp(data[parent], data[idx]) > 0) { |
|
swap(data, parent, idx); |
|
idx = parent; |
|
parent = parentIdx(idx); |
|
} |
|
}, |
|
_heapifyDown: function(idx) { |
|
var size = this.size; |
|
var cmp = this._cmp; |
|
var data = this._data; |
|
while (leftChildIdx(idx) < size) { |
|
var smallerIdx = leftChildIdx(idx); |
|
var rightChild = rightChildIdx(idx); |
|
if ( |
|
rightChild < size && |
|
cmp(data[rightChildIdx], data[smallerIdx]) < 0 |
|
) { |
|
smallerIdx = rightChild; |
|
} |
|
if (cmp(data[idx], data[smallerIdx]) < 0) { |
|
break; |
|
} else { |
|
swap(data, idx, smallerIdx); |
|
} |
|
idx = smallerIdx; |
|
} |
|
} |
|
}); |
|
function parentIdx(idx) { |
|
return Math.floor((idx - 1) / 2); |
|
} |
|
function leftChildIdx(idx) { |
|
return 2 * idx + 1; |
|
} |
|
function rightChildIdx(idx) { |
|
return 2 * idx + 2; |
|
} |
|
|
|
module.exports = exports;
|
|
|