forked from trekhleb/javascript-algorithms
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dijkstra.js
63 lines (51 loc) · 1.97 KB
/
dijkstra.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
import PriorityQueue from '../../../data-structures/priority-queue/PriorityQueue';
/**
* @param {Graph} graph
* @param {GraphVertex} startVertex
*/
export default function dijkstra(graph, startVertex) {
const distances = {};
const visitedVertices = {};
const previousVertices = {};
const queue = new PriorityQueue();
// Init all distances with infinity assuming that currently we can't reach
// any of the vertices except start one.
graph.getAllVertices().forEach((vertex) => {
distances[vertex.getKey()] = Infinity;
previousVertices[vertex.getKey()] = null;
});
distances[startVertex.getKey()] = 0;
// Init vertices queue.
queue.add(startVertex, distances[startVertex.getKey()]);
while (!queue.isEmpty()) {
const currentVertex = queue.poll();
graph.getNeighbors(currentVertex).forEach((neighbor) => {
// Don't visit already visited vertices.
if (!visitedVertices[neighbor.getKey()]) {
// Update distances to every neighbor from current vertex.
const edge = graph.findEdge(currentVertex, neighbor);
const existingDistanceToNeighbor = distances[neighbor.getKey()];
const distanceToNeighborFromCurrent = distances[currentVertex.getKey()] + edge.weight;
if (distanceToNeighborFromCurrent < existingDistanceToNeighbor) {
distances[neighbor.getKey()] = distanceToNeighborFromCurrent;
// Change priority.
if (queue.hasValue(neighbor)) {
queue.changePriority(neighbor, distances[neighbor.getKey()]);
}
// Remember previous vertex.
previousVertices[neighbor.getKey()] = currentVertex;
}
// Add neighbor to the queue for further visiting.
if (!queue.hasValue(neighbor)) {
queue.add(neighbor, distances[neighbor.getKey()]);
}
}
});
// Add current vertex to visited ones.
visitedVertices[currentVertex.getKey()] = currentVertex;
}
return {
distances,
previousVertices,
};
}