Skip to content

Commit

Permalink
Added priority queue.
Browse files Browse the repository at this point in the history
  • Loading branch information
jeantimex committed Feb 6, 2018
1 parent 81f97ee commit df53107
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 16 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
"scripts": {
"lint": "./node_modules/.bin/eslint ./src",
"mocha": "cross-env NODE_ENV=test ./node_modules/.bin/nyc mocha ./src/**/*$FILE*-test.js",
"mocha-dev": "cross-env NODE_ENV=test ./node_modules/.bin/nyc mocha --watch ./src/**/*$FILE*-test.js",
"test": "npm run lint && npm run mocha",
"test-dev": "npm run lint && npm run mocha-dev",
"coverage": "./node_modules/.bin/nyc report --reporter=text-lcov | coveralls",
"release": "release-it"
},
Expand Down
75 changes: 75 additions & 0 deletions src/common/__tests__/priority-queue-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { assert } from 'chai';
import PriorityQueue from '../priority-queue';

describe('Priority Queue', () => {
it('should create a priority queue with default comparator', () => {
const pq = new PriorityQueue();
pq.offer(2);
pq.offer(1);
assert.equal(pq.poll(), 1);
assert.equal(pq.poll(), 2);
});

it('should use the specified comparator', () => {
const pq = new PriorityQueue({ comparator: (a, b) => b - a });
pq.offer(2);
pq.offer(1);
assert.equal(pq.poll(), 2);
assert.equal(pq.poll(), 1);
});

it('should throw empty queue error when peeking empty queue', () => {
const pq = new PriorityQueue();
assert.throws(() => pq.peek(), Error, 'Empty Queue');
});

it('should return the first element', () => {
const pq = new PriorityQueue({ initialValues: [3, 1, 2] });
assert.equal(pq.peek(), 1);
});

it('should return the first element', () => {
const pq = new PriorityQueue({ comparator: (a, b) => b - a, initialValues: [3, 1, 2] });
assert.equal(pq.peek(), 3);
});

it('should offer new value and bubble up', () => {
const pq = new PriorityQueue({ initialValues: [3, 1, 2] });
pq.offer(0);
assert.equal(pq.peek(), 0);
});

it('should offer new value and bubble up', () => {
const pq = new PriorityQueue({ comparator: (a, b) => b - a, initialValues: [3, 1, 2] });
pq.offer(4);
assert.equal(pq.peek(), 4);
});

it('should throw empty queue error when polling empty queue', () => {
const pq = new PriorityQueue();
assert.throws(() => pq.poll(), Error, 'Empty Queue');
});

it('should poll the data and bubble down the queue', () => {
const pq = new PriorityQueue({ initialValues: [3, 1, 2] });
pq.poll();
assert.equal(pq.peek(), 2);
});

it('should clear the queue', () => {
const pq = new PriorityQueue({ initialValues: [3, 1, 2] });
assert.equal(pq.size(), 3);
pq.clear();
assert.equal(pq.size(), 0);
});

it('should return the array of the queue', () => {
const pq = new PriorityQueue({ initialValues: [3, 1, 2] });
assert.deepEqual(pq.toArray(), [1, 2, 3]);
});

it('should return the array of the queue with specified comparator', () => {
const pq = new PriorityQueue({ comparator: (a, b) => b - a, initialValues: [3, 1, 2] });
assert.deepEqual(pq.toArray(), [3, 2, 1]);
});
});
44 changes: 28 additions & 16 deletions src/common/priority-queue.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,18 @@
*/

export default class PriorityQueue {
constructor({ comparator, initialValues }) {
this.comparator = comparator || ((a, b) => a - b);
this.data = initialValues ? initialValues.slice(0) : [];
constructor({ comparator = (a, b) => a - b, initialValues = [] } = {}) {
this.comparator = comparator;
this.data = initialValues;
this.heapify();
}

size() {
return this.data.length;
}

heapify() {
if (this.data.length > 0) {
for (let i = 0; i < this.data.length; i++) {
this.bubbleUp(i);
}
peek() {
if (this.size() === 0) {
throw new Error('Empty Queue');
}

return this.data[0];
}

offer(value) {
Expand All @@ -27,6 +23,10 @@ export default class PriorityQueue {
}

poll() {
if (this.size() === 0) {
throw new Error('Empty Queue');
}

const result = this.data[0];
const last = this.data.pop();

Expand All @@ -38,14 +38,26 @@ export default class PriorityQueue {
return result;
}

peek() {
return this.data[0];
}

clear() {
this.data = [];
}

size() {
return this.data.length;
}

toArray() {
return this.data.slice(0).sort(this.comparator);
}

heapify() {
if (this.data.length > 0) {
for (let i = 1; i < this.data.length; i++) {
this.bubbleUp(i);
}
}
}

bubbleUp(pos) {
while (pos > 0) {
let parent = (pos - 1) >>> 1;
Expand Down

0 comments on commit df53107

Please sign in to comment.