Frontend Labs
⋯

22. Dijkstra's Algorithm (Shortest Path)

🧸 ELI5: You're using GPS to find the fastest way to grandma's house, and some roads are slower than others (traffic, distance). Dijkstra's algorithm always explores the closest unvisited place first (using a heap/priority queue, like #19!), gradually building the shortest-distance map to everywhere from your starting point.

🌍 Real life: GPS/Google Maps shortest route calculation. Network routers finding the fastest path for your internet data to travel. Flight-booking sites finding the cheapest connecting flights.

📝 Pseudocode:

function dijkstra(graph, start):
    distances = { all nodes: infinity }
    distances[start] = 0
    priorityQueue = [(0, start)]

    while priorityQueue is not empty:
        (dist, current) = extractMin(priorityQueue)
        for (neighbor, weight) in graph[current]:
            newDist = dist + weight
            if newDist < distances[neighbor]:
                distances[neighbor] = newDist
                priorityQueue.add((newDist, neighbor))
    return distances

🐹 Go:

package main

import (
	"container/heap"
	"fmt"
	"math"
)

type Edge struct {
	to     string
	weight int
}

type Item struct {
	node string
	dist int
}

type PriorityQueue []Item

func (pq PriorityQueue) Len() int            { return len(pq) }
func (pq PriorityQueue) Less(i, j int) bool  { return pq[i].dist < pq[j].dist }
func (pq PriorityQueue) Swap(i, j int)       { pq[i], pq[j] = pq[j], pq[i] }
func (pq *PriorityQueue) Push(x interface{}) { *pq = append(*pq, x.(Item)) }
func (pq *PriorityQueue) Pop() interface{} {
	old := *pq
	n := len(old)
	item := old[n-1]
	*pq = old[:n-1]
	return item
}

func dijkstra(graph map[string][]Edge, start string) map[string]int {
	distances := make(map[string]int)
	for node := range graph {
		distances[node] = math.MaxInt32
	}
	distances[start] = 0

	pq := &PriorityQueue{{node: start, dist: 0}}
	heap.Init(pq)

	for pq.Len() > 0 {
		current := heap.Pop(pq).(Item)
		for _, edge := range graph[current.node] {
			newDist := current.dist + edge.weight
			if newDist < distances[edge.to] {
				distances[edge.to] = newDist
				heap.Push(pq, Item{node: edge.to, dist: newDist})
			}
		}
	}
	return distances
}

func main() {
	roadMap := map[string][]Edge{
		"Home":   {{"School", 5}, {"Park", 2}},
		"Park":   {{"School", 1}},
		"School": {},
	}
	fmt.Println(dijkstra(roadMap, "Home"))
	// Home:0, Park:2, School:3 (Home->Park->School is faster than Home->School directly!)
}

🇨 C — this version picks the closest unvisited place with a plain O(V) scan each round instead of #19's heap, trading O((V+E) log V) for a simpler O(V²); wiring the heap from #19 into this loop instead of the scan is exactly how you'd get the faster version:

#include <stdio.h>
#include <limits.h>
#include <string.h>

#define MAX_NODES 8

typedef struct {
    char names[MAX_NODES][32];
    int  weight[MAX_NODES][MAX_NODES]; // 0 = no direct road
    int  num_nodes;
} RoadMap;

int roadmap_add_node(RoadMap *g, const char *name) {
    strncpy(g->names[g->num_nodes], name, 31);
    return g->num_nodes++;
}

void roadmap_add_road(RoadMap *g, int a, int b, int weight) {
    g->weight[a][b] = weight;   // directed; call twice for a two-way road
}

void dijkstra(RoadMap *g, int start, int *dist) {
    int visited[MAX_NODES] = {0};
    for (int i = 0; i < g->num_nodes; i++) dist[i] = INT_MAX;
    dist[start] = 0;

    for (int iter = 0; iter < g->num_nodes; iter++) {
        int current = -1;
        for (int i = 0; i < g->num_nodes; i++) {      // pick the closest unvisited place —
            if (!visited[i] && (current == -1 || dist[i] < dist[current])) current = i;
        }
        if (current == -1 || dist[current] == INT_MAX) break;
        visited[current] = 1;

        for (int next = 0; next < g->num_nodes; next++) {
            if (g->weight[current][next] > 0 && dist[current] + g->weight[current][next] < dist[next]) {
                dist[next] = dist[current] + g->weight[current][next];
            }
        }
    }
}

int main(void) {
    RoadMap roadMap = {0};
    int home = roadmap_add_node(&roadMap, "Home");
    int park = roadmap_add_node(&roadMap, "Park");
    int school = roadmap_add_node(&roadMap, "School");

    roadmap_add_road(&roadMap, home, school, 5);
    roadmap_add_road(&roadMap, home, park, 2);
    roadmap_add_road(&roadMap, park, school, 1);

    int dist[MAX_NODES];
    dijkstra(&roadMap, home, dist);

    for (int i = 0; i < roadMap.num_nodes; i++) printf("%s:%d ", roadMap.names[i], dist[i]);
    printf("\n"); // Home:0 Park:2 School:3 — Home->Park->School beats Home->School directly
    return 0;
}

⏱️ Complexity: O((V + E) log V) using a heap — fast enough for GPS to recalculate routes on the fly.


Generated from real-life-ds-algo-guide.md · 8 Oct 2026 16:36