|
| 1 | +package algorithms.graph |
| 2 | + |
| 3 | +import datastructures.graph.Graph |
| 4 | +import datastructures.basic.PriorityQueue |
| 5 | +import scala.collection.mutable |
| 6 | + |
| 7 | +/// Dijkstra's Algorithm |
| 8 | +/// Finds the shortest paths from a starting node to all other nodes in a weighted graph |
| 9 | +/// Uses a priority queue-based approach |
| 10 | +/// Runs in O((V + E) log V) time complexity |
| 11 | + |
| 12 | +def dijkstra[T](graph: Graph[T], start: T): Unit = { |
| 13 | + val distances = mutable.Map[T, Int]().withDefaultValue(Int.MaxValue) |
| 14 | + val visited = mutable.Set[T]() |
| 15 | + val priorityQueue = PriorityQueue[(T, Int)]()(Ordering.by(-_._2)) |
| 16 | + |
| 17 | + distances(start) = 0 |
| 18 | + priorityQueue.enqueue((start, 0)) |
| 19 | + while (!priorityQueue.isEmpty) { |
| 20 | + val (currentNode: T, currentDistance: Int) = priorityQueue.dequeue().get // unsafe getter for now |
| 21 | + if (!visited.contains(currentNode)) { |
| 22 | + visited.add(currentNode) |
| 23 | + |
| 24 | + for ((neighbor, weight) <- graph.getNeighbors(currentNode)) { |
| 25 | + if (!visited.contains(neighbor)) { |
| 26 | + val newDistance = currentDistance + weight |
| 27 | + if (newDistance < distances(neighbor)) { |
| 28 | + distances(neighbor) = newDistance.toInt |
| 29 | + priorityQueue.enqueue((neighbor, newDistance.toInt)) |
| 30 | + } |
| 31 | + } |
| 32 | + } |
| 33 | + } |
| 34 | + } |
| 35 | + |
| 36 | + distances.toMap |
| 37 | + |
| 38 | +} |
0 commit comments