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.
80 lines
2.1 KiB
80 lines
2.1 KiB
2 years ago
|
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;
|