Dijkstra’s Algorithm: A Complete Guide for 2025
Updated on Jun 23, 2025 | 19 min read | 4.01K+ views
Share:
For working professionals
For fresh graduates
More
Updated on Jun 23, 2025 | 19 min read | 4.01K+ views
Share:
Table of Contents
Do you know? Dijkstra’s Algorithm, first published in 1959, remains one of the fastest known single-source shortest-path algorithms for graphs with non-negative weights, achieving a time complexity as low as Θ(∣E∣+∣V∣log∣V∣) when using a Fibonacci heap. It is up to seven orders of magnitude faster than basic approaches in some cases. |
Dijkstra's Algorithm is a method used to find the shortest path between two nodes in a graph. It works by progressively exploring paths and selecting the one with the least cost.
Widely used in navigation systems, such as Google Maps, it helps determine the quickest routes based on distance and road conditions. The algorithm’s ability to optimize routes makes it essential in modern applications like GPS navigation, network routing, and traffic management, ensuring efficiency in real-world systems.
In this blog, you'll learn how Dijkstra’s Algorithm works, step-by-step, and how it is applied to find the shortest path in various real-world scenarios.
If you want to explore the more advanced algorithms, upGrad’s online data science courses can help you. Along with improving your knowledge in Python, Machine Learning, AI, Tableau and SQL, you will gain practical insights and hands-on experience to tackle real-world problems.
Imagine you’re navigating a map with various cities connected by roads of different lengths, and you need to find the shortest route between two cities. The algorithm finds the shortest path by exploring nodes with the smallest known distance, updating paths until it reaches the destination.
In 2025, professionals who can use advanced algorithms to improve business operations will be in high demand. If you're looking to develop relevant data science skills, here are some top-rated courses to help you get there:
Now, let’s look at how Dijkstra’s Algorithm works:
1. Initialize: Start with the source node, setting its distance to zero and all other nodes' distances to infinity.
2. Visit the Nearest Node: Choose the node with the smallest known distance and explore its neighbors.
3. Update Distances: For each neighboring node, check if the new path is shorter than the previously known path.
4. Repeat: Visit the nearest node, update distances, and continue until all nodes are explored or the destination is reached.
Also Read: What are Data Structures & Algorithm
Before going deeper into Dijkstra's Algorithm, let's clarify some important fundamental terms:
Fundamental Terms in Djikstra’s Algorithm
Also Read: A Guide to the Types of AI Algorithms and Their Applications
Let’s break down Dijkstra’s Algorithm with a simple example. Suppose you have four cities (A, B, C, D), and we need to find the shortest path from city A to city D.
The roads between them have different lengths:
Now, let’s apply Dijkstra’s shortest path algorithm.
Start with the source city (A). Set the distance to A as 0 and all others as infinity.
A |
B |
C |
D |
0 | ∞ | ∞ | ∞ |
From city A, the only two reachable cities are B and C. Update their distances.
A |
B |
C |
D |
0 | 5 | 10 | ∞ |
Next, choose the city with the smallest distance: city B. From B, we can reach C and D.
A |
B |
C |
D |
0 | 5 | 8 | 7 |
Now, visit city D because it has the smallest distance (7). From D, there’s no shorter path to any other city, so we can move on to the final step.
At this point, we’ve found the shortest path to city D, and the total distance is 7.
To make it even clearer, here’s a simple visual diagram:
This visual shows the cities (nodes) and roads (edges) between them, along with the weights (distances) marked on the edges.
The shortest path from A to D is A → B → D, with a total distance of 7.
Also Read: Computer Vision Algorithms: Everything You Need To Know [2025]
Pseudocode for Dijkstra’s Algorithm:
1. Initialize the Distances: Set the distance of all nodes to infinity, except for the starting node, which is set to 0.
2. Create a Priority Queue: Add the starting node to the priority queue with a distance of 0.
3. Process the Queue: While the queue is not empty:
4. Repeat: Continue the process until all nodes are processed or the destination node is reached.
Also Read: What is Kruskal’s Algorithm? Steps, Examples, Overview
Now that you’ve got the theory down, it’s time to turn those concepts into code.
There are several ways to approach Dijkstra’s Algorithm, each varying in complexity and efficiency. From simple arrays to more advanced data structures like priority queues, your chosen method can significantly impact the algorithm's performance, especially in large-scale problems.
One of the most straightforward and commonly used approaches is implementing Dijkstra’s Algorithm with an adjacency matrix.
A common approach to implementing Dijkstra’s Algorithm is using an adjacency matrix, which represents the graph as a 2D array. Each element shows the weight of the edge between nodes, with infinity indicating no edge.
This method is intuitive and works well for dense graphs, where most nodes are connected. However, for larger graphs, its space complexity can become inefficient.
Let’s break down how Dijkstra’s Algorithm works when implemented with an adjacency matrix.
1. Initialize the Matrix: Create a matrix where each element represents the edge weight between nodes. If no edge exists, set the value to infinity. The diagonal is set to 0, representing the distance from a node to itself.
2. Distance Array: Initialize an array to store the shortest distance from the starting node to all others. Set the starting node’s distance to 0 and all others to infinity.
3. Visited Array: Create an array to track visited nodes, preventing revisits and ensuring efficiency during the algorithm.
4. Iterate through Nodes: For each unvisited node, calculate the tentative distance through its neighbors. If a shorter path is found, update the distance.
5. Repeat: Continue this process until the shortest path to all nodes has been determined.
Code Example:
import sys
# Function to implement Dijkstra's Algorithm using an adjacency matrix
def dijkstra(matrix, start_node):
n = len(matrix) # Number of nodes
dist = [sys.maxsize] * n # Initialize all distances to infinity
dist[start_node] = 0 # Distance to start node is 0
visited = [False] * n # To keep track of visited nodes
for _ in range(n):
# Find the node with the minimum distance that hasn't been visited
min_dist = sys.maxsize
min_index = -1
for i in range(n):
if not visited[i] and dist[i] < min_dist:
min_dist = dist[i]
min_index = i
visited[min_index] = True # Mark the node as visited
# Update distances for the neighbors of the current node
for j in range(n):
if not visited[j] and matrix[min_index][j] != sys.maxsize:
new_dist = dist[min_index] + matrix[min_index][j]
if new_dist < dist[j]:
dist[j] = new_dist
return dist
# Example graph represented by an adjacency matrix
# Example: 0,1,2,3,4 are nodes and values represent the edge weights
graph = [ [0, 5, sys.maxsize, sys.maxsize, 10],
[5, 0, 3, sys.maxsize, sys.maxsize],
[sys.maxsize, 3, 0, 1, sys.maxsize],
[sys.maxsize, sys.maxsize, 1, 0, 2],
[10, sys.maxsize, sys.maxsize, 2, 0]
]
# Running Dijkstra's Algorithm from node 0
start_node = 0
distances = dijkstra(graph, start_node)
print("Shortest distances from node 0:", distances)
Explanation of Code:
Output:
Shortest distances from node 0: [0, 5, 8, 7, 7]
Time Complexity:
The time complexity of Dijkstra’s Algorithm using an adjacency matrix is O(n^2), where n is the number of nodes.
This is due to the algorithm needing to examine each of the n nodes and check all other n nodes to find the one with the smallest tentative distance.
While this approach is efficient for small graphs, its quadratic time complexity can lead to slower performance as the number of nodes increases, making it less suitable for large graphs.
Trouble working efficiently with data in Python? Enhance your Python skills with the Learn Python Libraries: NumPy, Matplotlib & Pandas. This free course by upGrad is designed to help you work more efficiently with data.
An adjacency list is a more efficient graph representation compared to the adjacency matrix. Instead of using a 2D array to represent all possible edges, an adjacency list stores each node’s neighbors along with the corresponding edge weights.
This representation is especially useful for sparse graphs, where most nodes are not connected. Using an adjacency list can reduce space complexity and improve the algorithm’s performance in large graphs.
1. Initialize the List: For each node, create a list that stores its neighbors and the corresponding edge weights. If a node has no neighbors, its list is empty.
2. Distance Array: Create an array to store the shortest distance from the starting node to all other nodes. Set the distance of the starting node to 0 and all others to infinity.
3. Visited Array: Use a visited array to track nodes that have already been processed. This ensures we don’t revisit nodes and improves efficiency.
4. Iterate through Nodes: For each unvisited node, explore its neighbors. Calculate the tentative distance to each neighbor and update the shortest distance if a shorter path is found.
5. Repeat: Continue the process until the shortest path to all nodes has been determined.
Code Example:
import heapq
def dijkstra(adj_list, start_node):
n = len(adj_list)
dist = [float('inf')] * n
dist[start_node] = 0
visited = [False] * n
min_heap = [(0, start_node)] # (distance, node)
while min_heap:
current_dist, current_node = heapq.heappop(min_heap)
if visited[current_node]:
continue
visited[current_node] = True
for neighbor, weight in adj_list[current_node]:
if visited[neighbor]:
continue
new_dist = current_dist + weight
if new_dist < dist[neighbor]:
dist[neighbor] = new_dist
heapq.heappush(min_heap, (new_dist, neighbor))
return dist
# Example graph represented as an adjacency list
# Example: 0,1,2,3,4 are nodes and values represent the edge weights
graph = [ [(1, 5), (4, 10)], # Node 0
[(0, 5), (2, 3)], # Node 1
[(1, 3), (3, 1)], # Node 2
[(2, 1), (4, 2)], # Node 3
[(0, 10), (3, 2)] # Node 4
]
# Running Dijkstra's Algorithm from node 0
start_node = 0
distances = dijkstra(graph, start_node)
print("Shortest distances from node 0:", distances)
Explanation:
Output:
Shortest distances from node 0: [0, 5, 8, 7, 7]
Also Read: Deep Learning Algorithm [Comprehensive Guide With Examples]
When implementing Dijkstra’s Algorithm, one common optimization is using a min-heap (priority queue) to improve the algorithm’s efficiency. In earlier approaches, we manually searched for the node with the smallest distance, which could be time-consuming, especially for large graphs.
By using a priority queue, we can automatically retrieve the smallest distance node in O(log V) time, drastically improving performance.
Step-by-Step Explanation:
1. Priority Queue Initialization: Use a priority queue (min-heap) to store the nodes with their current shortest distance. This allows us to efficiently extract the node with the smallest distance.
2. Distance Array: Initialize the distance array with infinity, setting the distance to the starting node as 0.
3. Visited Array: Keep track of visited nodes to avoid re-processing them.
4. Process Nodes: Extract the node with the smallest tentative distance from the priority queue. For each of its neighbors, calculate the new distance and, if it’s shorter, update the distance and add the neighbor to the priority queue.
5. Repeat: Continue processing nodes until the shortest path to all nodes has been determined.
Code Example:
import heapq
def dijkstra_min_heap(adj_list, start_node):
n = len(adj_list)
dist = [float('inf')] * n
dist[start_node] = 0
visited = [False] * n
min_heap = [(0, start_node)] # (distance, node)
while min_heap:
current_dist, current_node = heapq.heappop(min_heap)
if visited[current_node]:
continue
visited[current_node] = True
for neighbor, weight in adj_list[current_node]:
if visited[neighbor]:
continue
new_dist = current_dist + weight
if new_dist < dist[neighbor]:
dist[neighbor] = new_dist
heapq.heappush(min_heap, (new_dist, neighbor))
return dist
# Example graph represented as an adjacency list
graph = [ [(1, 5), (4, 10)], # Node 0
[(0, 5), (2, 3)], # Node 1
[(1, 3), (3, 1)], # Node 2
[(2, 1), (4, 2)], # Node 3
[(0, 10), (3, 2)] # Node 4
]
# Running Dijkstra's Algorithm with min-heap from node 0
start_node = 0
distances = dijkstra_min_heap(graph, start_node)
print("Shortest distances from node 0:", distances)
Explanation:
Output:
Shortest distances from node 0: [0, 5, 8, 7, 7]
Time Complexity:
The time complexity of this optimized version using a priority queue is O(E log V), where E is the number of edges and V is the number of vertices. This is because:
This is a significant improvement over the O(n^2) complexity with the adjacency matrix, making this approach much more efficient for larger graphs.
Also Read: Heap Sort in Data Structures: Usability and Performance
In many real-world applications, you may only need to find the shortest path from a source node to a single destination vertex rather than all nodes in the graph. Modifying Dijkstra’s Algorithm to stop once the destination node is reached can significantly improve performance, especially in large graphs where calculating paths to all nodes is unnecessary.
This optimized approach focuses on terminating the algorithm early, making it more efficient for specific use cases like route planning or network analysis.
Step-by-Step Explanation:
1. Initialize the Graph: Start by setting up the graph and initializing the distance array to infinity, with the distance to the starting node set to 0.
2. Priority Queue: Use a priority queue (min-heap) to select the node with the smallest tentative distance.
3. Process Nodes: Extract nodes from the priority queue, update distances to their neighbors, and push these neighbors back into the queue if a shorter path is found.
4. Early Termination: As soon as the destination node is reached, stop further processing. This avoids unnecessary computations for nodes that won’t be part of the shortest path.
5. Repeat: The algorithm continues until the destination node is reached or all reachable nodes have been processed.
Code Example:
import heapq
def dijkstra_single_destination(adj_list, start_node, destination_node):
n = len(adj_list)
dist = [float('inf')] * n
dist[start_node] = 0
visited = [False] * n
min_heap = [(0, start_node)] # (distance, node)
while min_heap:
current_dist, current_node = heapq.heappop(min_heap)
if current_node == destination_node:
break # Stop as soon as we reach the destination node
if visited[current_node]:
continue
visited[current_node] = True
for neighbor, weight in adj_list[current_node]:
if visited[neighbor]:
continue
new_dist = current_dist + weight
if new_dist < dist[neighbor]:
dist[neighbor] = new_dist
heapq.heappush(min_heap, (new_dist, neighbor))
return dist[destination_node]
# Example graph represented as an adjacency list
graph = [ [(1, 5), (4, 10)], # Node 0
[(0, 5), (2, 3)], # Node 1
[(1, 3), (3, 1)], # Node 2
[(2, 1), (4, 2)], # Node 3
[(0, 10), (3, 2)] # Node 4
]
# Running Dijkstra's Algorithm from node 0 to node 3
start_node = 0
destination_node = 3
distance = dijkstra_single_destination(graph, start_node, destination_node)
print(f"Shortest distance from node {start_node} to node {destination_node}: {distance}")
Explanation:
Output:
Shortest distance from node 0 to node 3: 7
Time Complexity:
The time complexity for this approach remains O(E log V), as the priority queue still needs to handle edge updates, and the graph is processed through the min-heap.
By terminating early when the destination is found, the algorithm processes fewer nodes. This can significantly improve practical runtime in many scenarios, especially when the destination is far from the source.
Selecting the right approach can significantly improve both performance and computational efficiency depending on the problem at hand.
Are you a full-stack developer wanting to integrate AI into your workflow? upGrad’s AI-Driven Full-Stack Development bootcamp can help you. You’ll learn how to build AI-powered software using OpenAI, GitHub Copilot, Bolt AI & more.
Also Read: Top 14 Most Common Data Mining Algorithms You Should Know
With these various techniques in hand, let’s now look at how Dijkstra’s Algorithm is put to use in real-world applications.
Industries like telecommunications, logistics, and robotics rely on Dijkstra’s shortest path algorithm to optimize everything from network traffic to vehicle routes and robotic movement.
Here’s how it’s applied across different sectors:
Industry |
Application |
Example |
Telecommunications | Ensuring data packets travel the most efficient path across complex networks. | Used by internet providers to route data efficiently through large networks, minimizing delays. |
Logistics | Finding the quickest routes for delivery vehicles or shipments. | Companies like UPS or FedEx use Dijkstra’s algorithm to optimize delivery routes, saving time and fuel costs. |
Robotics | Enabling robots to navigate efficiently in dynamic environments. | In autonomous vehicles and drones, Dijkstra’s algorithm helps plot the best paths while avoiding obstacles. |
Transportation | Calculating the shortest travel times for users. | GPS systems like Google Maps and Waze use Dijkstra's algorithm to suggest the quickest routes for drivers. |
Project Management | Finding the optimal sequence of tasks to minimize project time. | In project management software, Dijkstra’s algorithm helps determine the most efficient task dependencies. |
Whether it’s minimizing delivery times or routing data through vast networks, this algorithm plays a critical role in real-world applications.
Also Read: 48 Software Engineering Projects in 2025 With Source Code
Now that we’ve seen Dijkstra’s Algorithm in action, let’s break down its strengths and limitations to know when it’s most effective.
Dijkstra’s Algorithm is a powerful tool for finding the shortest path, but like any algorithm, it has both strengths and limitations. One of its key strengths is its efficiency in finding the shortest path in graphs with non-negative weights, making it ideal for applications like GPS navigation and network routing.
However, it has limitations, such as its inability to handle graphs with negative weight edges and its performance in dense graphs, where it may become slower compared to other algorithms like A* or Bellman-Ford.
Below is a breakdown of where it excels, where it may fall short, and how you can overcome its shortcomings:
Strengths |
Limitations |
Workarounds |
Efficiency in dense graphs: Dijkstra’s Algorithm excels in graphs with many edges, as it finds the shortest path in O(E log V) time with a priority queue. | Inefficient for large, sparse graphs: The algorithm can be slow for graphs with fewer edges, as it may still process a lot of unnecessary nodes. | Use A Search* or Bellman-Ford Algorithm for sparse graphs or cases with negative weights. |
Simplicity in implementation: It’s straightforward to implement using adjacency matrices or lists, making it an excellent starting point for pathfinding problems. | Space complexity: Storing the graph as an adjacency matrix takes up O(n^2) space, which is inefficient for large graphs. | Switch to an adjacency list to reduce space usage, especially for sparse graphs. |
Widely applicable: Dijkstra’s Algorithm is useful in navigation systems, network routing, and robotic path planning, where finding the shortest route is crucial. | Doesn’t handle negative weights: The algorithm doesn’t work if the graph has edges with negative weights. | Use Bellman-Ford Algorithm for graphs with negative edge weights, or apply a modified Dijkstra's approach with constraint handling. |
Optimal for single-source shortest path: It’s ideal when you only need the shortest path from one source to all other nodes. | Not ideal for multiple destination queries: For multiple destinations, recalculating paths for each destination can be inefficient. | Use Floyd-Warshall for frequent all-pairs queries or modify it to stop early for single-destination searches. |
Also Read: Top 9 Data Science Algorithms Every Data Scientist Should Know
Now that you are familiar with Dijkstra’s Algorithm, let’s look at how upGrad can help you learn data structures and algorithms.
Dijkstra’s Algorithm is crucial for solving real-world problems like optimizing routes in networks and GPS navigation. Learning this algorithm is essential for anyone pursuing careers in software development, data science, or network engineering, as it provides a strong foundation in problem-solving and optimization.
upGrad’s courses offer expert-led tutorials, hands-on coding exercises, and real-world applications, helping you master Dijkstra’s Algorithm and other key concepts. With upGrad, you can confidently tackle complex problems and advance your career in tech.
In addition to the programs covered above, here are some additional courses that can complement your learning journey:
If you're unsure where to begin or which area to focus on, upGrad’s expert career counselors can guide you based on your goals. You can also visit a nearby upGrad offline center to explore course options, get hands-on experience, and speak directly with mentors!
Boost your career with our popular Software Engineering courses, offering hands-on training and expert guidance to turn you into a skilled software developer.
Master in-demand Software Development skills like coding, system design, DevOps, and agile methodologies to excel in today’s competitive tech industry.
Stay informed with our widely-read Software Development articles, covering everything from coding techniques to the latest advancements in software engineering.
Reference Link:
https://ds2-iiith.vlabs.ac.in/exp/dijkstra-algorithm/analysis/time-and-space-complexity.html
900 articles published
Director of Engineering @ upGrad. Motivated to leverage technology to solve problems. Seasoned leader for startups and fast moving orgs. Working on solving problems of scale and long term technology s...
Get Free Consultation
By submitting, I accept the T&C and
Privacy Policy
India’s #1 Tech University
Executive PG Certification in AI-Powered Full Stack Development
77%
seats filled
Top Resources