Before diving into the algorithm, let's honor its creator: Edsger W. Dijkstra (1930-2002), a Dutch computer scientist and one of the pioneers of programming as a discipline. His contributions include:
Dijkstra's work laid foundations for modern computer science, particularly in algorithm design and programming methodology.
To understand this algorithm we first need to understand weighted graphs, I won't go into much details about graphs themselves since I did a blog post which you can find in my blog post on graphs. What I will do is highlight the major difference between them.
| Feature | Unweighted Graph | Weighted Graph |
|---|---|---|
| Representation | Array of connected nodes | Array of objects with node and weight properties |
| Path Calculation | Counts hops/edges | Sums weights |
| Example Use Case | Social network connections | GPS navigation routes |
Why weights matter: In real-world scenarios, connections often have a weight (distance, time, money). A weighted graph models these relationships more accurately.
Consider this graph:
A --2--> B | | 1 | 3 | | C --4--> D
The shortest path from A to D is A→B→D (total weight = 5)
class PriorityQueue {
constructor() {
this.values = [];
}
enqueue(val, priority) {
this.values.push({ val, priority });
this.sort();
}
dequeue() {
return this.values.shift();
}
sort() {
this.values.sort((a, b) => a.priority - b.priority);
}
}
class WeightedGraph {
constructor() {
this.adjacencyList = {};
}
addVertex(vertex) {
if (!this.adjacencyList[vertex]) this.adjacencyList[vertex] = [];
}
addEdge(v1, v2, weight) {
this.adjacencyList[v1].push({ node: v2, weight });
this.adjacencyList[v2].push({ node: v1, weight }); // For undirected graph
}
Dijkstra(start, finish) {
const nodes = new PriorityQueue();
const distances = {};
const previous = {};
let path = [];
let smallest;
// Initialize distances and priority queue
for (let vertex in this.adjacencyList) {
if (vertex === start) {
distances[vertex] = 0;
nodes.enqueue(vertex, 0);
} else {
distances[vertex] = Infinity;
nodes.enqueue(vertex, Infinity);
}
previous[vertex] = null;
}
while (nodes.values.length) {
smallest = nodes.dequeue().val;
if (smallest === finish) {
// Reconstruct path
while (previous[smallest]) {
path.push(smallest);
smallest = previous[smallest];
}
break;
}
if (smallest && distances[smallest] !== Infinity) {
for (let neighbor of this.adjacencyList[smallest]) {
// Calculate new distance
let candidate = distances[smallest] + neighbor.weight;
if (candidate < distances[neighbor.node]) {
distances[neighbor.node] = candidate;
previous[neighbor.node] = smallest;
nodes.enqueue(neighbor.node, candidate);
}
}
}
}
return path.concat(smallest).reverse();
}
}
// Usage Example:
const graph = new WeightedGraph();
graph.addVertex("A");
graph.addVertex("B");
graph.addVertex("C");
graph.addVertex("D");
graph.addEdge("A", "B", 1);
graph.addEdge("A", "C", 1);
graph.addEdge("B", "D", 3);
graph.addEdge("C", "D", 4);
console.log(graph.Dijkstra("A", "D")); // Output: ["A", "B", "D"]
Explanation:
Infinity except the start node (distance = 0)previous objectDijkstra algorithm is useful in various real-world applications:
With V being the number of vertices and E the number of edges.
That's it for Dijkstra's algorithm. I hope you learned as much as I did. If you have any questions or suggestions please hit me up!
Honestly i am no one, i've just been coding for 3 years now and i like to document every solutions to every problem i encounter. Extracting as much code snippets and tutorials i can so that if i ever need it again i just have to pop back here and get a quick refresher.
Feel free to me through this learning journey by providing any feedback and if you wanna support me: