( graph: number[][], src: number )
| 22 | * @complexity Time O(V²) | Space O(V) |
| 23 | */ |
| 24 | const dijkstra = ( |
| 25 | graph: number[][], |
| 26 | src: number |
| 27 | ): { distances: number[]; predecessors: Record<number, number[]> } => { |
| 28 | const dist: number[] = []; |
| 29 | const visited: boolean[] = []; |
| 30 | const pred: (number | null)[] = []; // Predecessor array |
| 31 | const { length } = graph; |
| 32 | for (let i = 0; i < length; i++) { |
| 33 | dist[i] = INF; |
| 34 | visited[i] = false; |
| 35 | pred[i] = null; // Initialize predecessors |
| 36 | } |
| 37 | dist[src] = 0; |
| 38 | for (let i = 0; i < length - 1; i++) { |
| 39 | const unv = minDistance(dist, visited); |
| 40 | visited[unv] = true; |
| 41 | for (let v = 0; v < length; v++) { |
| 42 | if (!visited[v] && graph[unv][v] !== 0 && dist[unv] !== INF && dist[unv] + graph[unv][v] < dist[v]) { |
| 43 | dist[v] = dist[unv] + graph[unv][v]; |
| 44 | pred[v] = unv; // Update predecessor |
| 45 | } |
| 46 | } |
| 47 | } |
| 48 | |
| 49 | // Construct paths from predecessors |
| 50 | const paths: Record<number, number[]> = {}; |
| 51 | for (let i = 0; i < length; i++) { |
| 52 | paths[i] = []; |
| 53 | let crawl: number = i; |
| 54 | paths[i].push(crawl); |
| 55 | while (pred[crawl] !== null) { |
| 56 | paths[i].push(pred[crawl]!); |
| 57 | crawl = pred[crawl]!; |
| 58 | } |
| 59 | paths[i].reverse(); |
| 60 | } |
| 61 | return { distances: dist, predecessors: paths }; |
| 62 | }; |
| 63 | |
| 64 | export default dijkstra; |
no test coverage detected