|
1 | 1 | # @datastructures-js/priority-queue |
2 | 2 |
|
3 | | -[](https://www.npmjs.com/package/@datastructures-js/priority-queue) |
4 | | -[](https://www.npmjs.com/package/@datastructures-js/priority-queue) [](https://www.npmjs.com/package/@datastructures-js/priority-queue) |
5 | | - |
6 | | -A heap-based implementation of priority queue in javascript with typescript support. |
7 | | - |
8 | | -<img src="https://user-images.githubusercontent.com/6517308/121813242-859a9700-cc6b-11eb-99c0-49e5bb63005b.jpg"> |
9 | | - |
10 | | - |
11 | | -# Contents |
12 | | -* [Install](#install) |
13 | | -* [require](#require) |
14 | | -* [import](#import) |
15 | | -* [API](#api) |
16 | | - * [constructor](#constructor) |
17 | | - * [fromArray](#fromarray) |
18 | | - * [enqueue (push)](#enqueue-push) |
19 | | - * [front](#front) |
20 | | - * [back](#back) |
21 | | - * [dequeue (pop)](#dequeue-pop) |
22 | | - * [contains](#contains) |
23 | | - * [remove](#remove) |
24 | | - * [isEmpty](#isEmpty) |
25 | | - * [size](#size) |
26 | | - * [toArray](#toarray) |
27 | | - * [Symbol.iterator](#symboliterator) |
28 | | - * [clear](#clear) |
29 | | - * [Build](#build) |
30 | | - * [License](#license) |
31 | | - |
32 | | -## Install |
33 | | - |
34 | | -```sh |
35 | | -npm install --save @datastructures-js/priority-queue |
36 | | -``` |
37 | | - |
38 | | -## API |
39 | | -PriorityQueue class allows using a compare function between values. MinPriorityQueue & MaxPriorityQueue can be used for primitive values and objects with known comparison prop. |
40 | | - |
41 | | -### require |
42 | | - |
43 | | -```js |
44 | | -const { |
45 | | - PriorityQueue, |
46 | | - MinPriorityQueue, |
47 | | - MaxPriorityQueue, |
48 | | -} = require('@datastructures-js/priority-queue'); |
49 | | -``` |
50 | | - |
51 | | -### import |
52 | | - |
53 | | -```js |
54 | | -import { |
55 | | - PriorityQueue, |
56 | | - MinPriorityQueue, |
57 | | - MaxPriorityQueue, |
58 | | - ICompare, |
59 | | - IGetCompareValue, |
60 | | -} from '@datastructures-js/priority-queue'; |
61 | | -``` |
62 | | - |
63 | | -### constructor |
64 | | -#### PriorityQueue |
65 | | -constructor requires a compare function that works similar to javascript sort callback, returning a number bigger than 0, means swap elements. |
66 | | - |
67 | | -##### TS |
68 | | -```ts |
69 | | -interface ICar { |
70 | | - year: number; |
71 | | - price: number; |
72 | | -} |
73 | | - |
74 | | -const compareCars: ICompare<ICar> = (a: ICar, b: ICar) => { |
75 | | - if (a.year > b.year) { |
76 | | - return -1; |
77 | | - } |
78 | | - if (a.year < b.year) { |
79 | | - // prioritize newest cars |
80 | | - return 1; |
81 | | - } |
82 | | - // with lowest price |
83 | | - return a.price < b.price ? -1 : 1; |
84 | | -}; |
85 | | - |
86 | | -const carsQueue = new PriorityQueue<ICar>(compareCars); |
87 | | -``` |
88 | | - |
89 | | -##### JS |
90 | | -```js |
91 | | -const carsQueue = new PriorityQueue((a, b) => { |
92 | | - if (a.year > b.year) { |
93 | | - return -1; |
94 | | - } |
95 | | - if (a.year < b.year) { |
96 | | - // prioratize newest cars |
97 | | - return 1; |
98 | | - } |
99 | | - // with lowest price |
100 | | - return a.price < b.price ? -1 : 1; |
101 | | - } |
102 | | -); |
103 | | -``` |
104 | | - |
105 | | -#### MinPriorityQueue, MaxPriorityQueue |
106 | | -constructor requires a callback for object values to indicate which prop is used for comparison, and does not require any for primitive values like numbers or strings. |
107 | | - |
108 | | -##### TS |
109 | | -```ts |
110 | | -const numbersQueue = new MinPriorityQueue<number>(); |
111 | | - |
112 | | -interface IBid { |
113 | | - id: number; |
114 | | - value: number; |
115 | | -} |
116 | | -const getBidValue: IGetCompareValue<IBid> = (bid) => bid.value; |
117 | | -const bidsQueue = new MaxPriorityQueue<IBid>(getBidValue); |
118 | | -``` |
119 | | - |
120 | | -##### JS |
121 | | -```js |
122 | | -const numbersQueue = new MinPriorityQueue(); |
123 | | -const bidsQueue = new MaxPriorityQueue((bid) => bid.value); |
124 | | -``` |
125 | | - |
126 | | -##### Legacy Compare Function (v5 compatibility) |
127 | | -For backward compatibility with v5, you can also pass a compare function in an options object: |
128 | | - |
129 | | -```js |
130 | | -// MinPriorityQueue with legacy compare |
131 | | -const minQueue = new MinPriorityQueue({ compare: (a, b) => a - b }); |
132 | | - |
133 | | -// MaxPriorityQueue with legacy compare |
134 | | -const maxQueue = new MaxPriorityQueue({ compare: (a, b) => a - b }); |
135 | | -``` |
136 | | - |
137 | | -This format is supported for backward compatibility with v5 of the library. |
138 | | - |
139 | | -### fromArray |
140 | | -If the queue is being created from an existing array, and there is no desire to use an extra O(n) space, this static function can turn an array into a priority queue in O(n) runtime. |
141 | | - |
142 | | -#### PriorityQueue |
143 | | -##### TS |
144 | | -```ts |
145 | | -const numbers = [3, -2, 5, 0, -1, -5, 4]; |
146 | | - |
147 | | -const pq = PriorityQueue.fromArray<number>(numbers, (a, b) => a - b); |
148 | | - |
149 | | -console.log(numbers); // [-5, -1, -2, 3, 0, 5, 4] |
150 | | -pq.dequeue(); // -5 |
151 | | -pq.dequeue(); // -2 |
152 | | -pq.dequeue(); // -1 |
153 | | -console.log(numbers); // [ 0, 3, 4, 5 ] |
154 | | -``` |
155 | | - |
156 | | -##### JS |
157 | | -```ts |
158 | | -const numbers = [3, -2, 5, 0, -1, -5, 4]; |
159 | | - |
160 | | -const pq = PriorityQueue.fromArray(numbers, (a, b) => a - b); |
161 | | - |
162 | | -console.log(numbers); // [-5, -1, -2, 3, 0, 5, 4] |
163 | | -pq.dequeue(); // -5 |
164 | | -pq.dequeue(); // -2 |
165 | | -pq.dequeue(); // -1 |
166 | | -console.log(numbers); // [ 0, 3, 4, 5 ] |
167 | | -``` |
168 | | - |
169 | | -#### MinPriorityQueue, MaxPriorityQueue |
170 | | -##### TS |
171 | | -```ts |
172 | | -const numbers = [3, -2, 5, 0, -1, -5, 4]; |
173 | | - |
174 | | -const mpq = MaxPriorityQueue.fromArray<number>(numbers); |
175 | | - |
176 | | -console.log(numbers); // [-5, -1, -2, 3, 0, 5, 4] |
177 | | -mpq.dequeue(); // 5 |
178 | | -mpq.dequeue(); // 4 |
179 | | -mpq.dequeue(); // 3 |
180 | | -console.log(numbers); // [ 0, -1, -5, -2 ] |
181 | | -``` |
182 | | - |
183 | | -##### JS |
184 | | -```ts |
185 | | -const numbers = [3, -2, 5, 0, -1, -5, 4]; |
186 | | - |
187 | | -const mpq = MaxPriorityQueue.fromArray(numbers); |
188 | | - |
189 | | -console.log(numbers); // [-5, -1, -2, 3, 0, 5, 4] |
190 | | -mpq.dequeue(); // 5 |
191 | | -mpq.dequeue(); // 4 |
192 | | -mpq.dequeue(); // 3 |
193 | | -console.log(numbers); // [ 0, -1, -5, -2 ] |
194 | | -``` |
195 | | - |
196 | | -### enqueue (push) |
197 | | -adds a value based on its comparison with other values in the queue in O(log(n)) runtime. |
198 | | - |
199 | | -```js |
200 | | -const cars = [ |
201 | | - { year: 2013, price: 35000 }, |
202 | | - { year: 2010, price: 2000 }, |
203 | | - { year: 2013, price: 30000 }, |
204 | | - { year: 2017, price: 50000 }, |
205 | | - { year: 2013, price: 25000 }, |
206 | | - { year: 2015, price: 40000 }, |
207 | | - { year: 2022, price: 70000 } |
208 | | -]; |
209 | | -cars.forEach((car) => carsQueue.enqueue(car)); |
210 | | - |
211 | | -const numbers = [3, -2, 5, 0, -1, -5, 4]; |
212 | | -numbers.forEach((num) => numbersQueue.push(num)); // push is an alias for enqueue |
213 | | - |
214 | | -const bids = [ |
215 | | - { id: 1, value: 1000 }, |
216 | | - { id: 2, value: 20000 }, |
217 | | - { id: 3, value: 1000 }, |
218 | | - { id: 4, value: 1500 }, |
219 | | - { id: 5, value: 12000 }, |
220 | | - { id: 6, value: 4000 }, |
221 | | - { id: 7, value: 8000 } |
222 | | -]; |
223 | | -bids.forEach((bid) => bidsQueue.enqueue(bid)); |
224 | | -``` |
225 | | - |
226 | | -### front |
227 | | -peeks on the value with highest priority in the queue. |
228 | | - |
229 | | -```js |
230 | | -console.log(carsQueue.front()); // { year: 2022, price: 70000 } |
231 | | -console.log(numbersQueue.front()); // -5 |
232 | | -console.log(bidsQueue.front()); // { id: 2, value: 20000 } |
233 | | -``` |
234 | | - |
235 | | -### back |
236 | | -peeks on the value with a lowest priority in the queue. |
237 | | - |
238 | | -```js |
239 | | -console.log(carsQueue.back()); // { year: 2010, price: 2000 } |
240 | | -console.log(numbersQueue.back()); // 5 |
241 | | -console.log(bidsQueue.back()); // { id: 1, value: 1000 } |
242 | | -``` |
243 | | - |
244 | | -### dequeue (pop) |
245 | | -removes and returns the element with highest priority in the queue in O(log(n)) runtime. |
246 | | - |
247 | | -```js |
248 | | -console.log(carsQueue.dequeue()); // { year: 2022, price: 70000 } |
249 | | -console.log(carsQueue.dequeue()); // { year: 2017, price: 50000 } |
250 | | -console.log(carsQueue.dequeue()); // { year: 2015, price: 40000 } |
251 | | - |
252 | | -console.log(numbersQueue.dequeue()); // -5 |
253 | | -console.log(numbersQueue.dequeue()); // -2 |
254 | | -console.log(numbersQueue.dequeue()); // -1 |
255 | | - |
256 | | -console.log(bidsQueue.pop()); // { id: 2, value: 20000 } |
257 | | -console.log(bidsQueue.pop()); // { id: 5, value: 12000 } |
258 | | -console.log(bidsQueue.pop()); // { id: 7, value: 8000 } |
259 | | -``` |
260 | | - |
261 | | -### contains |
262 | | -checks if the queue contains an element that meet a criteria in O(n*log(n)) runtime. |
263 | | - |
264 | | -```js |
265 | | -carsQueue.contains((car) => car.price === 50000); // true |
266 | | -carsQueue.contains((car) => car.price === 200000); // false |
267 | | -numbersQueue.contains((n) => n === 4); // true |
268 | | -numbersQueue.contains((n) => n === 10); // false |
269 | | -``` |
270 | | - |
271 | | -### remove |
272 | | -removes all elements that meet a criteria in O(n*log(n)) runtime and returns a list of the removed elements. |
273 | | - |
274 | | -```js |
275 | | -carsQueue.remove((car) => car.price === 35000); // [{ year: 2013, price: 35000 }] |
276 | | - |
277 | | -numbersQueue.remove((n) => n === 4); // [4] |
278 | | - |
279 | | -bidsQueue.remove((bid) => bid.id === 3); // [{ id: 3, value: 1000 }] |
280 | | -``` |
281 | | - |
282 | | -### isEmpty |
283 | | -checks if the queue is empty. |
284 | | - |
285 | | -```js |
286 | | -console.log(carsQueue.isEmpty()); // false |
287 | | -console.log(numbersQueue.isEmpty()); // false |
288 | | -console.log(bidsQueue.isEmpty()); // false |
289 | | -``` |
290 | | - |
291 | | -### size |
292 | | -returns the number of elements in the queue. |
293 | | - |
294 | | -```js |
295 | | -console.log(carsQueue.size()); // 3 |
296 | | -console.log(numbersQueue.size()); // 3 |
297 | | -console.log(bidsQueue.size()); // 3 |
298 | | -``` |
299 | | - |
300 | | -### toArray |
301 | | -returns a sorted array of elements by their priorities from highest to lowest in O(n*log(n)) runtime. |
302 | | - |
303 | | -```js |
304 | | -console.log(carsQueue.toArray()); |
305 | | -/* |
306 | | -[ |
307 | | - { year: 2013, price: 25000 }, |
308 | | - { year: 2013, price: 30000 }, |
309 | | - { year: 2010, price: 2000 } |
310 | | -] |
311 | | -*/ |
312 | | - |
313 | | -console.log(numbersQueue.toArray()); // [ 0, 3, 5 ] |
314 | | - |
315 | | -console.log(bidsQueue.toArray()); |
316 | | -/* |
317 | | -[ |
318 | | - { id: 6, value: 4000 }, |
319 | | - { id: 4, value: 1500 }, |
320 | | - { id: 1, value: 1000 } |
321 | | -] |
322 | | -*/ |
323 | | -``` |
324 | | - |
325 | | -### Symbol.iterator |
326 | | -The queues implement a Symbol.iterator that makes them iterable on `pop`. |
327 | | -```js |
328 | | -console.log([...carsQueue]); |
329 | | -/* |
330 | | -[ |
331 | | - { year: 2013, price: 25000 }, |
332 | | - { year: 2013, price: 30000 }, |
333 | | - { year: 2010, price: 2000 } |
334 | | -] |
335 | | -*/ |
336 | | -console.log(carsQueue.size()); // 0 |
337 | | - |
338 | | -console.log([...numbersQueue]); // [ 0, 3, 5 ] |
339 | | -console.log(numbersQueue.size()); // 0 |
340 | | - |
341 | | -for (const bid of bidsQueue) { |
342 | | - console.log(bid); |
343 | | -} |
344 | | -/* |
345 | | -{ id: 6, value: 4000 }, |
346 | | -{ id: 4, value: 1500 }, |
347 | | -{ id: 1, value: 1000 } |
348 | | -*/ |
349 | | -console.log(bidsHeap.size()); // 0 |
350 | | -``` |
351 | | - |
352 | | -### clear |
353 | | -clears all elements in the queue. |
354 | | - |
355 | | -```js |
356 | | -carsQueue.clear(); |
357 | | -console.log(carsQueue.size()); // 0 |
358 | | -console.log(carsQueue.front()); // null |
359 | | -console.log(carsQueue.dequeue()); // null |
360 | | -console.log(carsQueue.isEmpty()); // true |
361 | | - |
362 | | -numbersQueue.clear(); |
363 | | -console.log(numbersQueue.size()); // 0 |
364 | | -console.log(numbersQueue.front()); // null |
365 | | -console.log(numbersQueue.dequeue()); // null |
366 | | -console.log(numbersQueue.isEmpty()); // true |
367 | | - |
368 | | -bidsQueue.clear(); |
369 | | -console.log(bidsQueue.size()); // 0 |
370 | | -console.log(bidsQueue.front()); // null |
371 | | -console.log(bidsQueue.dequeue()); // null |
372 | | -console.log(bidsQueue.isEmpty()); // true |
373 | | -``` |
374 | | - |
375 | | -## Build |
376 | | -``` |
377 | | -grunt build |
378 | | -``` |
379 | | - |
380 | | -## License |
381 | | -The MIT License. Full License is [here](https://github.com/datastructures-js/priority-queue/blob/master/LICENSE) |
| 3 | +## Docs |
| 4 | +https://datastructures-js.info/docs/priority-queue |
0 commit comments