View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All

Exploring Dijkstra’s Algorithm: Step-by-Step Guide to Finding the Shortest Path

By Pavan Vadapalli

Updated on Apr 24, 2025 | 19 min read | 3.77K+ views

Share:

Dijkstra’s Algorithm is a graph search algorithm that finds the shortest path between two points in a network, making it essential for navigation and routing systems. However, understanding how it works can be tricky without a clear guide.

This article will break down the process with a practical dijkstra's shortest path algorithm example. You'll learn the concept step by step and see how to apply it in real-world scenarios. Let’s dive in!

Understanding Dijkstra's Algorithm with Examples

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.

Here’s how the 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.

Before we jump into the dijkstra's algorithm example, let's clarify some important fundamental terms:

  • Nodes: These are the points or vertices in the graph, representing locations like cities on a map.
  • Edges: The connections between nodes, representing the roads between cities in a map.
  • Weights: Each edge has a weight, representing the distance or cost of traveling between two nodes.
  • Priority Queue: A data structure that helps manage nodes by always selecting the one with the smallest distance to explore next.

Coverage of AWS, Microsoft Azure and GCP services

Certification8 Months

Job-Linked Program

Bootcamp36 Weeks

If you’re looking to move beyond theory and apply Dijkstra’s Shortest Path Algorithm to real-world problems, check out upGrad’s computer science courses. Learn to implement algorithms efficiently, optimize large-scale solutions, and work on industry-impacting projects.

Let’s break this down with a simple dijkstra's algorithm 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:

  • A to B: 5
  • A to C: 10
  • B to C: 3
  • B to D: 2
  • C to D: 1

Now, let’s apply Dijkstra’s shortest path algorithm.

Step 1: Initialize the distances

Start with the source city (A). Set the distance to A as 0 and all others as infinity: 

A

B

C

D

0

Step 2: Visit the nearest node (A)

From city A, the only two reachable cities are B and C. Update their distances:

  • Distance to B = 5 (from A to B)
  • Distance to C = 10 (from A to C)

A

B

C

D

0 5 10

Step 3: Visit the next nearest node (B)

Next, choose the city with the smallest distance: city B. From B, we can reach C and D:

  • Distance to C = 5 (from A to B) + 3 (from B to C) = 8 (which is shorter than 10, so we update it).
  • Distance to D = 5 (from A to B) + 2 (from B to D) = 7.

A

B

C

D

0 5 8 7

Step 4: Visit the next nearest node (D)

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.

Step 5: Reach the destination

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.

Pseudocode for Dijkstra’s Algorithm

1. Initialize the distances: set all nodes to infinity except for the starting node.

2. Create a priority queue and add the starting node with a distance of 0.

3. While the queue is not empty:

a. Remove the node with the smallest distance.

b. Update the neighbors' distances if a shorter path is found.

c. Add the neighbors to the queue if necessary.

4. Repeat until all nodes are processed or the destination is reached.

This algorithm is invaluable for tasks like optimizing network routes or planning efficient travel paths.

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.

Implementing Dijkstra’s Algorithm: A Step-by-Step Guide

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.

Dijkstra’s Algorithm Using 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.

Step-by-Step Explanation

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)

Output:

Shortest distances from node 0: [0, 5, 8, 7, 7]

Explanation of Code:

  • We define a function dijkstra that takes an adjacency matrix and a starting node.
  • The dist array holds the shortest distances from the start node to every other node, initially set to infinity except for the start node itself.
  • The algorithm iteratively selects the unvisited node with the smallest tentative distance and updates the distances to its neighbors.
  • The final result is an array of shortest distances from the start node to every other node.

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.

Pros:

  • Simple to implement and easy to understand.
  • The matrix allows direct access to edge weights, making the code clear and easy to follow.
  • More efficient for dense graphs with many connections.

Cons:

  • Takes up O(n^2) space, making it inefficient for sparse graphs.
  • Slower for large, sparse graphs compared to more advanced data structures like priority queues.

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.

Dijkstra’s Algorithm Using Adjacency List

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.

Step-by-Step Explanation

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)

Output

Shortest distances from node 0: [0, 5, 8, 7, 7]

Explanation:

  • The graph is an adjacency list, where each node points to a list of tuples containing a neighbor and the edge weight.
  • A priority queue (min-heap) is used always to select the node with the smallest tentative distance.
  • The dijkstra function starts by initializing the distance array with infinity, setting the distance to the starting node as 0.
  • The algorithm iteratively selects the node with the smallest distance, updates the distances to its neighbors, and processes the neighbors.
  • The output shows the shortest distances from node 0 to all other nodes.

Pros:

  • More space-efficient for sparse graphs, as it only stores edges that exist.
  • Reduces time complexity compared to the adjacency matrix, especially in large, sparse graphs.
  • The use of a priority queue improves the efficiency of finding the node with the smallest distance.

Cons:

  • More complex to implement compared to the adjacency matrix approach.
  • May still be less efficient for very dense graphs due to the overhead of maintaining the list structure.

Dijkstra’s Algorithm with Min-Heap (Priority Queue)

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)

Output

Shortest distances from node 0: [0, 5, 8, 7, 7]

Explanation:

  • In this implementation, we use a priority queue (min-heap) to always extract the node with the smallest tentative distance.
  • Each time we extract a node, we check its neighbors and update the distances accordingly. If we find a shorter path to a neighbor, we push the new distance back into the heap.
  • The heapq.heappop() function ensures that the node with the smallest distance is processed first.
  • The output shows the shortest distances from node 0 to all other nodes, which are calculated efficiently using the priority queue.

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:

  • Each edge is processed once.
  • For each edge, the distance is updated in the priority queue, which takes O(log V) time due to the heap operations (insertion and extraction).

This is a significant improvement over the O(n^2) complexity with the adjacency matrix, making this approach much more efficient for larger graphs. 

Pros:

  • The min-heap optimization reduces the time complexity to O(E log V), making it much more efficient for large graphs.
  • It efficiently handles sparse graphs by focusing on edge relaxation only when necessary.
  • The algorithm becomes faster with a priority queue compared to the naive approach of linear searching for the smallest distance.

Cons:

  • Slightly more complex to implement than basic adjacency matrix or list approaches.
  • Although it reduces time complexity, the space complexity is still O(E + V) due to the need to store the graph and the priority queue.

Also Read: Heap Sort in Data Structures: Usability and Performance

Dijkstra’s Algorithm with Single Destination Vertex

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}")

Output:

Shortest distance from node 0 to node 3: 7

Explanation:

  • This version of Dijkstra's shortest path algorithm is modified to stop when the destination node (node 3 in this case) is reached.
  • As soon as we extract node 3 from the priority queue, the algorithm halts and returns the shortest distance to the destination node.
  • The output shows the shortest path from node 0 to node 3, which is calculated efficiently without needing to process the entire graph.

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.

Pros:

  • Improved efficiency: Stops early when the destination node is reached, reducing unnecessary computation.
  • Faster for specific use cases: Ideal for applications like route planning where you only need the path to one specific node.
  • Less memory usage: As fewer nodes are processed, the algorithm uses less memory in practice.

Cons:

  • Limited use case: This optimization is only applicable when you only need the shortest path to a single destination.
  • Doesn’t work for all graphs: If you need to calculate shortest paths to multiple destinations, this approach isn't suitable.

Selecting the right approach can significantly improve both performance and computational efficiency depending on the problem at hand—whether you're working with dense graphs, large-scale datasets, or specific destination queries.

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.

Real-World Applications of Dijkstra’s Algorithm

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.

Strengths and Limitations of Dijkstra’s Algorithm

Dijkstra’s Algorithm is a powerful tool for finding the shortest path, but like any algorithm, it has both strengths and limitations. 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.

Dijkstra’s Algorithm remains one of the most essential tools for solving shortest path problems. However, as with any algorithm, it’s important to recognize its limitations and understand when to choose alternative approaches for maximum efficiency.

How Can upGrad Help You Gain Expertise Dijkstra’s Algorithm?

With a global network of over 10 million learners, upGrad offers industry-focused courses that help both beginners and experienced professionals master key concepts in computer science. 

These courses offer hands-on experience, bridging theory with real-world problem-solving. 

Here are some of the top recommended courses:

Struggling to choose the right career path? Consult upGrad’s expert counselors or visit an offline center to find a course that aligns with your goals!

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.

Frequently Asked Questions (FAQs)

1. How does Dijkstra’s Algorithm handle graphs with negative weights?

2. Can Dijkstra’s Algorithm be used for finding the shortest path in a directed graph?

3. Is Dijkstra’s shortest path algorithm optimal for large-scale graphs?

4. What is the time complexity of Dijkstra’s Algorithm using a priority queue?

5. Can Dijkstra’s Algorithm be used for all-pairs shortest path problems?

6. How does Dijkstra’s Algorithm compare with A Search*?

7. What are the key differences between Dijkstra’s Algorithm and the Bellman-Ford Algorithm?

8. Why does Dijkstra’s Algorithm fail on graphs with negative weight cycles?

9. Can Dijkstra’s Algorithm find the shortest path between two specific nodes only?

10. How do you visualize Dijkstra’s Algorithm with a simple example?

11. Is Dijkstra’s Algorithm efficient for real-time applications?

Pavan Vadapalli

900 articles published

Get Free Consultation

+91

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

View Program

Top Resources

Recommended Programs

upGrad

AWS | upGrad KnowledgeHut

AWS Certified Solutions Architect - Associate Training (SAA-C03)

69 Cloud Lab Simulations

Certification

32-Hr Training by Dustin Brimberry

upGrad KnowledgeHut

upGrad KnowledgeHut

Angular Training

Hone Skills with Live Projects

Certification

13+ Hrs Instructor-Led Sessions

upGrad

upGrad

AI-Driven Full-Stack Development

Job-Linked Program

Bootcamp

36 Weeks