From ce7a4a930f31b6cb0c3c35d5513939369802e7cf Mon Sep 17 00:00:00 2001 From: Oleksii Trekhleb Date: Thu, 3 May 2018 06:47:09 +0300 Subject: [PATCH] Add Dijkstra. --- src/algorithms/graph/dijkstra/dijkstra.js | 9 ++++- .../priority-queue/PriorityQueue.js | 38 +++++++++++++++---- .../__test__/PriorityQueue.test.js | 13 +++++++ 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/src/algorithms/graph/dijkstra/dijkstra.js b/src/algorithms/graph/dijkstra/dijkstra.js index 5e192feb..439efce3 100644 --- a/src/algorithms/graph/dijkstra/dijkstra.js +++ b/src/algorithms/graph/dijkstra/dijkstra.js @@ -33,10 +33,17 @@ export default function dijkstra(graph, startVertex) { if (distanceToNeighborFromCurrent < existingDistanceToNeighbor) { distances[neighbor.getKey()] = distanceToNeighborFromCurrent; + + // Change priority. + if (queue.hasValue(neighbor)) { + queue.changePriority(neighbor, distances[neighbor.getKey()]); + } } // Add neighbor to the queue for further visiting. - queue.add(neighbor, distances[neighbor.getKey()]); + if (!queue.hasValue(neighbor)) { + queue.add(neighbor, distances[neighbor.getKey()]); + } } }); diff --git a/src/data-structures/priority-queue/PriorityQueue.js b/src/data-structures/priority-queue/PriorityQueue.js index 32538a61..2bf27bb3 100644 --- a/src/data-structures/priority-queue/PriorityQueue.js +++ b/src/data-structures/priority-queue/PriorityQueue.js @@ -40,19 +40,28 @@ export default class PriorityQueue extends MinHeap { * @return {PriorityQueue} */ changePriority(item, priority) { - const customFindingComparator = new Comparator((a, b) => { - if (a === b) { - return 0; - } - return a < b ? -1 : 1; - }); - - this.remove(item, customFindingComparator); + this.remove(item, new Comparator(this.compareValue)); this.add(item, priority); return this; } + /** + * @param {*} item + * @return {Number[]} + */ + findByValue(item) { + return this.find(item, new Comparator(this.compareValue)); + } + + /** + * @param {*} item + * @return {boolean} + */ + hasValue(item) { + return this.findByValue(item).length > 0; + } + /** * @param {*} a * @param {*} b @@ -65,4 +74,17 @@ export default class PriorityQueue extends MinHeap { return this.priorities[a] < this.priorities[b] ? -1 : 1; } + + /** + * @param {*} a + * @param {*} b + * @return {number} + */ + compareValue(a, b) { + if (a === b) { + return 0; + } + + return a < b ? -1 : 1; + } } diff --git a/src/data-structures/priority-queue/__test__/PriorityQueue.test.js b/src/data-structures/priority-queue/__test__/PriorityQueue.test.js index 5d3a20fa..e5f490cd 100644 --- a/src/data-structures/priority-queue/__test__/PriorityQueue.test.js +++ b/src/data-structures/priority-queue/__test__/PriorityQueue.test.js @@ -87,4 +87,17 @@ describe('PriorityQueue', () => { expect(priorityQueue.poll()).toBe(15); expect(priorityQueue.poll()).toBe(10); }); + + it('should be possible to search in priority queue by value', () => { + const priorityQueue = new PriorityQueue(); + + priorityQueue.add(10, 1); + priorityQueue.add(5, 2); + priorityQueue.add(100, 0); + priorityQueue.add(200, 0); + priorityQueue.add(15, 15); + + expect(priorityQueue.hasValue(70)).toBeFalsy(); + expect(priorityQueue.hasValue(15)).toBeTruthy(); + }); });