|
| 1 | +class Graph { |
| 2 | + constructor() { |
| 3 | + this.adjacencyList = new Map(); |
| 4 | + } |
| 5 | + |
| 6 | + addVertex(vertex) { |
| 7 | + if (!this.adjacencyList.has(vertex)) { |
| 8 | + this.adjacencyList.set(vertex, []); |
| 9 | + } |
| 10 | + } |
| 11 | + |
| 12 | + addEdge(source, destination, weight) { |
| 13 | + if (!this.adjacencyList.has(source)) { |
| 14 | + this.addVertex(source); |
| 15 | + } |
| 16 | + if (!this.adjacencyList.has(destination)) { |
| 17 | + this.addVertex(destination); |
| 18 | + } |
| 19 | + this.adjacencyList.get(source).push({ node: destination, weight }); |
| 20 | + } |
| 21 | + |
| 22 | + dijkstra(start, end) { |
| 23 | + const distances = {}; |
| 24 | + const visited = new Set(); |
| 25 | + const priorityQueue = new Map(); |
| 26 | + const previous = {}; |
| 27 | + |
| 28 | + // Initialize distances and previous map |
| 29 | + for (let vertex of this.adjacencyList.keys()) { |
| 30 | + distances[vertex] = Infinity; |
| 31 | + previous[vertex] = null; |
| 32 | + } |
| 33 | + distances[start] = 0; |
| 34 | + priorityQueue.set(start, 0); |
| 35 | + |
| 36 | + while (priorityQueue.size > 0) { |
| 37 | + // Get the node with the smallest distance |
| 38 | + let [currentNode, currentDistance] = [...priorityQueue.entries()].reduce((a, b) => (a[1] < b[1] ? a : b)); |
| 39 | + priorityQueue.delete(currentNode); |
| 40 | + |
| 41 | + // If we reached the destination node, build and return the path |
| 42 | + if (currentNode === end) { |
| 43 | + const path = []; |
| 44 | + while (previous[currentNode]) { |
| 45 | + path.push(currentNode); |
| 46 | + currentNode = previous[currentNode]; |
| 47 | + } |
| 48 | + return { path: path.reverse(), distance: distances[end] }; |
| 49 | + } |
| 50 | + |
| 51 | + visited.add(currentNode); |
| 52 | + |
| 53 | + // Update distances and queue with neighbors |
| 54 | + for (let neighbor of this.adjacencyList.get(currentNode)) { |
| 55 | + if (!visited.has(neighbor.node)) { |
| 56 | + const newDist = currentDistance + neighbor.weight; |
| 57 | + if (newDist < distances[neighbor.node]) { |
| 58 | + distances[neighbor.node] = newDist; |
| 59 | + previous[neighbor.node] = currentNode; |
| 60 | + priorityQueue.set(neighbor.node, newDist); |
| 61 | + } |
| 62 | + } |
| 63 | + } |
| 64 | + } |
| 65 | + |
| 66 | + return { path: [], distance: Infinity }; // Path not found |
| 67 | + } |
| 68 | +} |
| 69 | + |
| 70 | +// Example Usage: |
| 71 | +const graph = new Graph(); |
| 72 | +graph.addVertex("A"); |
| 73 | +graph.addVertex("B"); |
| 74 | +graph.addVertex("C"); |
| 75 | +graph.addVertex("D"); |
| 76 | + |
| 77 | +graph.addEdge("A", "B", 5); |
| 78 | +graph.addEdge("A", "C", 2); |
| 79 | +graph.addEdge("B", "D", 1); |
| 80 | +graph.addEdge("C", "B", 8); |
| 81 | +graph.addEdge("C", "D", 7); |
| 82 | + |
| 83 | +const result = graph.dijkstra("A", "D"); |
| 84 | +console.log("Shortest path:", result.path); |
| 85 | +console.log("Shortest distance:", result.distance); |
0 commit comments