Chapters

Hide chapters

Data Structures & Algorithms in Swift

Fifth Edition · iOS 18 · Swift 6.0 · Xcode 16.2

42. Dijkstra’s Algorithm
Written by Vincent Ngo

Heads up... You’re accessing parts of this content for free, with some sections shown as dgfibjfeb text.

Heads up... You’re accessing parts of this content for free, with some sections shown as xkriqlzec text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

Have you ever used the Google or Apple Maps app to find the shortest distance or fastest time from one place to another? Dijkstra’s algorithm is particularly useful in GPS networks to help find the shortest path between two places.

Dijkstra’s algorithm is a greedy algorithm. A greedy algorithm constructs a solution step-by-step, and it picks the most optimal path at every step in isolation. It misses solutions where some steps might cost more, but the overall cost is lower. Nevertheless, it usually arrives at a pretty good solution very quickly.

Dijkstra’s algorithm finds the shortest paths between vertices in either directed or undirected graphs. Given a vertex in a graph, the algorithm will find all shortest paths from the starting vertex.

Some other applications of Dijkstra’s algorithm include:

  1. Communicable disease transmission: Discover where biological diseases are spreading the fastest.
  2. Telephone networks: Routing calls to highest-bandwidth paths available in the network.
  3. Mapping: Finding the shortest and fastest paths for travelers.

Example

All the graphs you have looked at thus far have been undirected. Let’s change it up a little and work with a directed graph! Imagine the directed graph below represents a GPS network:

The vertices represent physical locations, and the edges represent one-way paths of a given cost between locations.

3 9 2 8 2 1 1 3 1 8 5 2 3 1 H G C E B F A D

In Dijkstra’s algorithm, you first choose a starting vertex since the algorithm needs a starting point to find a path to the rest of the nodes in the graph. Assume the starting vertex you pick is vertex A.

First pass

3 9 2 8 2 1 1 3 1 8 5 2 3 1 A H F B D E C G 8 A 9 A 1 A nil nil nil nil B C D E F G H Start A

Heads up... You’re accessing parts of this content for free, with some sections shown as frnivrhoc text.

Heads up... You’re accessing parts of this content for free, with some sections shown as nhkijffar text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

Second pass

8 A 9 A 1 A nil nil nil nil B C D E F G H Start A

0 0 3 7 9 6 8 3 1 3 2 3 4 9 I C B X Z E X D Gcajv O 5 A 8 O rof yam man pul 5 O 8 O gaf beh rez 8 T 6 O 3 E J C D T U C H C

Third pass

Start A 8 A 9 A nil nil nil nil 8 A 9 A nil nil nil 4 G 1 A 1 A B G C D E F G H

4 0 5 3 6 1 3 0 9 6 5 7 7 8 U L X F W E Z Tposg U 1 E 3 O bez juf kat qen 9 O 7 U sen vib qoq 8 M 4 N 4 U 1 A 7 J 5 U 1 J jan qap 2 A B Z F B H O K B L L

Heads up... You’re accessing parts of this content for free, with some sections shown as zwrevlcon text.

Heads up... You’re accessing parts of this content for free, with some sections shown as pgmibdqaw text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

Fourth pass

Start A 8 A 9 A nil nil nil nil 8 A 9 A nil nil nil 4 G 4 G 1 A 1 A 7 C 9 A 5 C nil nil 1 A B G C C D E F G H

7 5 1 3 4 0 1 5 7 1 8 5 7 4 I D N Y W W Pnorw O 4 O 5 E hiy sub beg xoc 3 A 0 A vez gos tih 0 K 8 W 5 O 0 I 0 W 7 E goh nin 9 E 4 A 9 U 8 I vax 6 L 2 U 6 S 2 F F S C E V R A F V X B I

Fifth pass

Start A 8 A 9 A nil nil nil nil 8 A 9 A nil nil nil 4 G 4 G 1 A 1 A 7 C 9 A nil nil 1 A 6 E 9 A 7 E nil 4 G 1 A 5 C 5 C B G C E C D E F G H

Brutj A 9 I 4 U lug ruw rac zij 0 E 8 O xub tiq diw 5 T 2 H 0 I 9 A 0 Z 7 O dub cut 4 A 4 U 6 E 3 O dot 4 S 0 A 2 G 4 U 5 E puy 0 I 5 B 4 U 4 H 3 K B G G O J P C U G F Z 6 4 5 0 9 2 6 5 9 2 4 0 1 3 E R G X R L V E

Heads up... You’re accessing parts of this content for free, with some sections shown as szwalzsem text.

Heads up... You’re accessing parts of this content for free, with some sections shown as qzkubnmim text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

Sixth pass

Start A 8 A 9 A nil nil nil nil 8 A 9 A nil nil nil 4 G 4 G 1 A 1 A 7 C 9 A nil nil 1 A 6 E 9 A 7 E nil 4 G 1 A 5 C 9 A 7 E nil 6 E 4 G 1 A 5 C 5 C B G C E B C D E F G H

6 7 0 4 9 2 1 2 9 0 0 1 9 5 I K Q G M E R G Xvims A 5 O 2 I weq zej bac tiq 8 E 7 O pon deh zar 0 T 0 M 4 U 0 U 1 T 6 A 5 I 9 E wes zac kim 5 E 8 U 9 A 8 I 5 U 9 O 8 A rik 2 T 1 T 7 F 6 E 1 U 7 A 2 E 0 S 6 T 2 P 0 D D N C O H R P D E M N L ziy

Seventh pass

Start A 8 A 9 A nil nil nil nil 8 A 9 A nil nil nil 4 G 4 G 1 A 1 A 7 C 9 A 7 E 9 A nil nil nil 1 A 6 E 6 E 6 E 9 A 9 A 7 E nil 4 G 4 G 4 G 7 E 1 A 1 A 1 A 5 C 5 C 5 C 5 C B G C E B D C D E F G H nil

Fxolf I 4 O 5 A xic jer wax xij 8 O 2 U gah gib loq 3 W 5 G 8 E 5 A 7 Q 7 I 2 O 8 E yok boy ned sam 0 I 8 O 2 E 5 O 3 A 8 U 2 E 1 O qaz 4 R 3 R 4 M 8 S 2 U 8 O 5 I 4 A 9 A 5 O 7 L 2 Y 3 Q 5 M 8 O 5 X Y S R A X V P Z G I Y Z F 1 9 5 8 2 3 7 9 5 1 5 3 2 6 E R X S A S K H suj

Eighth pass

You have covered every vertex except for H. H has two outgoing edges to G and F. However, there is no path from A to H. Because there is no path, the whole column for H is nil.

Wxomb A 7 U 4 U lan ruy lax dak 3 O 5 I mal zum yip 7 J 0 X 1 A 1 E 1 W 0 O 8 E 4 O bic suv gaz rod 5 O 4 O 2 I 1 U 9 I 1 I 7 O 2 A xil 3 T 7 M 7 D 9 C 6 A 7 E 7 U 2 A 8 U 1 I 7 Y 4 F 5 H 1 F 0 U 5 C Z D R U B X D G L O X D S 6 0 8 4 5 9 8 0 5 6 7 0 4 5 U C Z L I R V B dam

Mwexk O 1 A 9 G 0 E 6 O 5 O kip sox qov jal piy wid nal juv 8 U 0 A dap fen mix 3 V 9 V 1 F 0 A 7 E 2 U 9 O quq zug 3 K 9 M 9 D 1 E 3 I 1 O 6 Y 4 S 8 M 4 O 0 A 0 E 0 A 4 I 3 U 7 I 5 E 0 A 1 A 9 Y 7 A 9 R L M Q I N J X Q W E S B N 8 1 4 5 7 8 4 6 9 0 7 6 2 8 M Y E A V D P K

Heads up... You’re accessing parts of this content for free, with some sections shown as qmtutkjij text.

Heads up... You’re accessing parts of this content for free, with some sections shown as wjgydqlet text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

Implementation

Open up the starter playground for this chapter. This playground comes with an adjacency list graph and a priority queue, which you will use to implement Dijkstra’s algorithm.

public enum Visit<T: Hashable> {
  case start // 1
  case edge(Edge<T>) // 2
}
public class Dijkstra<T: Hashable> {

  public typealias Graph = AdjacencyList<T>
  let graph: Graph

  public init(graph: Graph) {
    self.graph = graph
  }
}

Helper methods

Before building Dijkstra, let’s create some helper methods that will help create the algorithm.

Tracing back to the start

C to G to A G 3 9 2 8 2 1 1 3 1 8 5 2 3 1 H C E D B A F

private func route(to destination: Vertex<T>,
                   with paths: [Vertex<T> : Visit<T>]) -> [Edge<T>] {
  var vertex = destination // 1
  var path: [Edge<T>] = [] // 2

  while let visit = paths[vertex], case .edge(let edge) = visit { // 3
    path = [edge] + path // 4
    vertex = edge.source // 5
  }
  return path // 6
}

Heads up... You’re accessing parts of this content for free, with some sections shown as ncdoxfxot text.

Heads up... You’re accessing parts of this content for free, with some sections shown as vjjonlnoj text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

Calculating total distance

Total distance = 4 A G 3 1 C

private func distance(to destination: Vertex<T>,
                      with paths: [Vertex<T> : Visit<T>]) -> Double {
  let path = route(to: destination, with: paths) // 1
  let distances = path.compactMap { $0.weight } // 2
  return distances.reduce(0.0, +) // 3
}

Heads up... You’re accessing parts of this content for free, with some sections shown as rmduvtdox text.

Heads up... You’re accessing parts of this content for free, with some sections shown as vjqikwhew text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

Generating the shortest paths

After the distance method, add the following:

public func shortestPath(from start: Vertex<T>) -> [Vertex<T> : Visit<T>] {
  var paths: [Vertex<T> : Visit<T>] = [start: .start] // 1

  // 2
  var priorityQueue = PriorityQueue<Vertex<T>>(sort: {
    self.distance(to: $0, with: paths) <
    self.distance(to: $1, with: paths)
  })
  priorityQueue.enqueue(start) // 3

  // to be continued
}
while let vertex = priorityQueue.dequeue() { // 1
  for edge in graph.edges(from: vertex) { // 2
    guard let weight = edge.weight else { // 3
      continue
    }
    if paths[edge.destination] == nil ||
       distance(to: vertex, with: paths) + weight <
       distance(to: edge.destination, with: paths) { // 4
      paths[edge.destination] = .edge(edge)
      priorityQueue.enqueue(edge.destination)
    }
  }
}

return paths

Finding a specific path

Add the following method to class Dijkstra:

public func shortestPath(to destination: Vertex<T>,
                         paths: [Vertex<T> : Visit<T>]) -> [Edge<T>] {
  return route(to: destination, with: paths)
}

Trying out your code

3 9 2 8 2 1 1 3 1 8 5 2 3 1 H G C E B F A D

let dijkstra = Dijkstra(graph: graph)
let pathsFromA = dijkstra.shortestPath(from: a) // 1
let path = dijkstra.shortestPath(to: d, paths: pathsFromA) // 2
for edge in path { // 3
  print("\(edge.source) --|\(edge.weight ?? 0.0)|--> \(edge.destination)")
}

Heads up... You’re accessing parts of this content for free, with some sections shown as lfvevzcev text.

Heads up... You’re accessing parts of this content for free, with some sections shown as dvdyrpcij text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now
W 1 7 4 3 1 3 5 2 6 8 7 4 8 0 K D E F X E B

A --|1.0|--> G
G --|3.0|--> C
C --|1.0|--> E
E --|2.0|--> D

Performance

In Dijkstra’s algorithm, you constructed your graph using an adjacency list. You used a min-priority queue to store vertices and extract the vertex with the minimum path. This process has an overall time complexity of O(log V). The heap operations of extracting the minimum element or inserting an element both take O(log V) respectively.

Key points

  • Dijkstra’s algorithm finds a path to the rest of the nodes given a starting vertex.
  • This algorithm is useful for finding the shortest paths between different endpoints.
  • Visit state is used to track the edges back to the start vertex.
  • The priority queue data structure ensures returning the vertex with the shortest path.
  • Because it chooses the shortest path at each step, it is said to be greedy!
Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2025 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as sfvarpmaq text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now