forked from WG-SpaceCoder/AutoTrimps
-
Notifications
You must be signed in to change notification settings - Fork 51
/
FastPriorityQueue.js
130 lines (115 loc) · 3.38 KB
/
FastPriorityQueue.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**
* FastPriorityQueue.js : a fast heap-based priority queue in JavaScript.
* (c) the authors
* Licensed under the Apache License, Version 2.0.
*
* Speed-optimized heap-based priority queue for modern browsers and JavaScript engines.
*
* Usage :
Installation (in shell, if you use node):
$ npm install fastpriorityqueue
Running test program (in JavaScript):
// var FastPriorityQueue = require("fastpriorityqueue");// in node
var x = new FastPriorityQueue();
x.add(1);
x.add(0);
x.add(5);
x.add(4);
x.add(3);
x.peek(); // should return 0, leaves x unchanged
x.size; // should return 5, leaves x unchanged
while(!x.isEmpty()) {
console.log(x.poll());
} // will print 0 1 3 4 5
*/
'use strict';
var defaultcomparator = function(a, b) {
return a < b;
};
// the provided comparator function should take a, b and return *true* when a < b
function FastPriorityQueue(comparator) {
this.array = [];
this.size = 0;
this.compare = comparator || defaultcomparator;
}
// Add an element the the queue
// runs in O(log n) time
FastPriorityQueue.prototype.add = function(myval) {
var i = this.size;
this.array[this.size++] = myval;
while ( i > 0) {
var p = (i - 1) >> 1;
var ap = this.array[p];
if(!this.compare(myval, ap )) break;
this.array[i] = ap;
i = p;
}
this.array[i] = myval;
};
// replace the content of the heap by provided array and "heapifies it"
FastPriorityQueue.prototype.heapify = function(arr) {
this.array = arr;
this.size = arr.length;
for (var i = (this.size >> 1); i >= 0; i--) {
this._percolateDown(i);
}
};
// for internal use
FastPriorityQueue.prototype._percolateUp = function(i) {
var myval = this.array[i];
while ( i > 0) {
var p = (i - 1) >> 1;
var ap = this.array[p];
if(!this.compare(myval, ap )) break;
this.array[i] = ap;
i = p;
}
this.array[i] = myval;
};
// for internal use
FastPriorityQueue.prototype._percolateDown = function(i) {
var size = this.size;
var hsize = this.size >>> 1;
var ai = this.array[i];
while (i < hsize) {
var l = (i << 1) + 1;
var r = l + 1;
var bestc = this.array[l];
if (r < size) {
if (this.compare(this.array[r], bestc)) {
l = r;
bestc = this.array[r];
}
}
if (!this.compare(bestc,ai)) {
break;
}
this.array[i] = bestc;
i = l;
}
this.array[i] = ai;
};
//Look at the top of the queue (a smallest element)
// executes in constant time
FastPriorityQueue.prototype.peek = function(t) {
return this.array[0];
};
// remove the element on top of the heap (a smallest element)
// runs in logarithmic time
FastPriorityQueue.prototype.poll = function(i) {
var ans = this.array[0];
if(this.size > 1) {
this.array[0] = this.array[--this.size];
this._percolateDown(0 | 0);
}
else if (this.size == 0) --this.size;
return ans;
};
// recover unused memory (for long-running priority queues)
FastPriorityQueue.prototype.trim = function() {
this.array = this.array.slice(0,this.size);
};
// Check whether the heap is empty
FastPriorityQueue.prototype.isEmpty = function(i) {
return this.size == 0;
};