|
| 1 | +Priority Queue |
| 2 | +============== |
| 3 | + |
| 4 | +A priority queue is a data structure with these operations: |
| 5 | + |
| 6 | +| Operation | Syntax (js-priority-queue) | Description | |
| 7 | +| --------- | --- | ----------- | |
| 8 | +| Create | `var queue = new PriorityQueue();` | Creates a priority queue | |
| 9 | +| Queue | `queue.queue(value);` | Inserts a new value in the queue | |
| 10 | +| Length | `var length = queue.length;` | Returns the number of elements in the queue | |
| 11 | +| Peek | `var firstItem = queue.peek();` | Returns the smallest item in the queue and leaves the queue unchanged | |
| 12 | +| Dequeue | `var firstItem = queue.dequeue();` | Returns the smallest item in the queue and removes it from the queue | |
| 13 | + |
| 14 | +You cannot access the data in any other way: you must dequeue or peek. |
| 15 | + |
| 16 | +Why use this library? Two reasons: |
| 17 | + |
| 18 | +1. It's easier to use than an Array, and it's clearer. |
| 19 | +2. It can make your code execute more quickly. |
| 20 | + |
| 21 | +Installing |
| 22 | +========== |
| 23 | + |
| 24 | +Download `priority-queue.js`. Alternatively, install through Bower: |
| 25 | +`bower install js-priority-queue` |
| 26 | + |
| 27 | +Include it through [RequireJS](http://requirejs.org/). |
| 28 | + |
| 29 | +Then write code like this: |
| 30 | + |
| 31 | + require([ 'vendor/priority-queue' ], function(PriorityQueue) { |
| 32 | + var queue = new PriorityQueue({ comparator: function(a, b) { return b - a; }); |
| 33 | + queue.queue(5); |
| 34 | + queue.queue(3); |
| 35 | + queue.queue(2); |
| 36 | + var lowest = queue.pop(); // returns 2 |
| 37 | + }); |
| 38 | + |
| 39 | +If you don't like RequireJS, you can download the standalone version, |
| 40 | +`priority-queue.no-require.js`, and write: |
| 41 | + |
| 42 | + var queue = new PriorityQueue({ comparator: function(a, b) { return b - a; }); |
| 43 | + queue.queue(5); |
| 44 | + queue.queue(3); |
| 45 | + queue.queue(2); |
| 46 | + var lowest = queue.pop(); // returns 2 |
| 47 | + |
| 48 | +Options |
| 49 | +======= |
| 50 | + |
| 51 | +How exactly will these elements be ordered? Let's use the `comparator` option. |
| 52 | +This is the argument we would pass to |
| 53 | +[Array.prototype.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort): |
| 54 | + |
| 55 | + var compareNumbers = function(a, b) { return a - b; }; |
| 56 | + var queue = new PriorityQueue({ comparator: compareNumbers }); |
| 57 | + |
| 58 | +Strategies |
| 59 | +========== |
| 60 | + |
| 61 | +We can implement this with a regular `Array`. We'll keep it sorted inversely, |
| 62 | +so `queue.dequeue()` maps to `array.pop()`. |
| 63 | + |
| 64 | +But with an `Array`, we'll need to `splice()`, which can affect every single |
| 65 | +element in the array. An alternative is to create a |
| 66 | +[Binary Heap](http://en.wikipedia.org/wiki/Binary_heap), which writes far |
| 67 | +fewer array elements when queueing (though each element is written more slowly). |
| 68 | + |
| 69 | +Finally, we can use a [B-Heap](http://en.wikipedia.org/wiki/B-heap). It's like a |
| 70 | +binary heap, except it orders elements such that during a single operation, |
| 71 | +writes occur closer to each other in memory. That can give a speed win. |
| 72 | + |
| 73 | +Create the queues like this: |
| 74 | + |
| 75 | + var queue = new PriorityQueue({ strategy: PriorityQueue.ArrayStrategy }); // Array |
| 76 | + var queue = new PriorityQueue({ strategy: PriorityQueue.BinaryHeapStrategy }); // simple binary heap |
| 77 | + var queue = new PriorityQueue({ strategy: PriorityQueue.BHeapStrategy }); // default |
| 78 | + |
| 79 | +You'll see running times like this: |
| 80 | + |
| 81 | +| Operation | Array | Binary heap | B-Heap | |
| 82 | +| --------- | ----- | ----------- | -------------- | |
| 83 | +| Create | O(1) | O(1) | O(1) | |
| 84 | +| Queue | O(n) (often slow) | O(lg n) (fast) | O(lg n) (fast) | |
| 85 | +| Peek | O(1) | O(1) | O(1) | |
| 86 | +| Dequeue | O(1) | O(lg n) | O(lg n) | |
| 87 | + |
| 88 | +Contributing |
| 89 | +============ |
| 90 | + |
| 91 | +1. Fork this repository |
| 92 | +2. Run `npm install` |
| 93 | +3. Write the behavior you expect in `spec-coffee/` |
| 94 | +4. Edit files in `coffee/` until `grunt test` says you're done |
| 95 | +5. Run `grunt` to update `priority-queue.js` and `priority-queue.min.js` |
| 96 | +6. Submit a pull request |
| 97 | + |
| 98 | +License |
| 99 | +======= |
| 100 | + |
| 101 | +I, Adam Hooper, the sole author of this project, waive all my rights to it and |
| 102 | +release it under the [Public |
| 103 | +Domain](http://creativecommons.org/publicdomain/zero/1.0/). Do with it what you |
| 104 | +will. |
0 commit comments