diff --git a/src/main/java/com/thealgorithms/graph/DijkstraShortestPath.java b/src/main/java/com/thealgorithms/graph/DijkstraShortestPath.java new file mode 100644 index 000000000000..1ac1830b9e48 --- /dev/null +++ b/src/main/java/com/thealgorithms/graph/DijkstraShortestPath.java @@ -0,0 +1,37 @@ +import java.util.*; + +public class DijkstraShortestPath { + + public int[] shortestPath(int numNodes, Map> adjList, int startNode) { + int[] distances = new int[numNodes]; + Arrays.fill(distances, Integer.MAX_VALUE); + distances[startNode] = 0; + + PriorityQueue minHeap = new PriorityQueue<>(Comparator.comparingInt(a -> a[1])); + minHeap.offer(new int[] {startNode, 0}); + + while (!minHeap.isEmpty()) { + int[] current = minHeap.poll(); + int currentNode = current[0]; + int currentDistance = current[1]; + + if (currentDistance > distances[currentNode]) { + continue; + } + + for (int[] edge : adjList.getOrDefault(currentNode, Collections.emptyList())) { + int nextNode = edge[0]; + int edgeWeight = edge[1]; + int newDistance = distances[currentNode] + edgeWeight; + if (newDistance < distances[nextNode]) { + distances[nextNode] = newDistance; + minHeap.offer(new int[] {nextNode, newDistance}); + } + } + } + return distances; + } +} + +// wikipedia link +// https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm#:~:text=Dijkstra's%20algorithm%20(/%CB%88da%C9%AA,and%20published%20three%20years%20later. diff --git a/src/test/java/com/thealgorithms/graph/DijkstraShortestPathTest.java b/src/test/java/com/thealgorithms/graph/DijkstraShortestPathTest.java new file mode 100644 index 000000000000..70057a0acb08 --- /dev/null +++ b/src/test/java/com/thealgorithms/graph/DijkstraShortestPathTest.java @@ -0,0 +1,71 @@ +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class DijkstraShortestPathTest { + + private DijkstraShortestPath dijkstra; + + @BeforeEach + public void setUp() { + dijkstra = new DijkstraShortestPath(); + } + + @Test + public void testSinglePath() { + Map> adjList = new HashMap<>(); + adjList.put(0, List.of(new int[] {1, 1})); + adjList.put(1, List.of(new int[] {2, 1})); + adjList.put(2, List.of(new int[] {3, 1})); + adjList.put(3, new ArrayList<>()); + + int[] result = dijkstra.shortestPath(4, adjList, 0); + int[] expected = {0, 1, 2, 3}; + assertArrayEquals(expected, result, "Distances should match expected shortest path distances."); + } + + @Test + public void testDisconnectedGraph() { + Map> adjList = new HashMap<>(); + adjList.put(0, List.of(new int[] {1, 2})); + adjList.put(1, List.of(new int[] {2, 2})); + adjList.put(2, new ArrayList<>()); + adjList.put(3, new ArrayList<>()); + + int[] result = dijkstra.shortestPath(4, adjList, 0); + int[] expected = {0, 2, 4, Integer.MAX_VALUE}; + assertArrayEquals(expected, result, "Distances should match expected shortest path distances."); + } + + @Test + public void testComplexGraph() { + Map> adjList = new HashMap<>(); + adjList.put(0, List.of(new int[] {1, 4}, new int[] {2, 1})); + adjList.put(1, List.of(new int[] {3, 1})); + adjList.put(2, List.of(new int[] {1, 2}, new int[] {3, 5})); + adjList.put(3, new ArrayList<>()); + + int[] result = dijkstra.shortestPath(4, adjList, 0); + int[] expected = {0, 3, 1, 4}; + assertArrayEquals(expected, result, "Distances should match expected shortest path distances."); + } + + @Test + public void testRevisitedNodeWithHigherDistance() { + // graph is set up to test the condition where a node is revisited with a higher distance. + Map> adjList = new HashMap<>(); + adjList.put(0, List.of(new int[] {1, 5})); + adjList.put(1, List.of(new int[] {2, 1})); + adjList.put(2, List.of(new int[] {0, 3}, new int[] {3, 1})); + adjList.put(3, new ArrayList<>()); + + int[] result = dijkstra.shortestPath(4, adjList, 0); + int[] expected = {0, 5, 6, 7}; + assertArrayEquals(expected, result, "Distances should match expected shortest path distances."); + } +}