Menu
Coddy logo textTech

Dijkstra-Algorithmus

Zuletzt aktualisiert

Der Dijkstra-Algorithmus findet den kürzesten Weg von einem Startknoten zu allen anderen Knoten in einem Graphen mit nicht negativen Kantengewichten. Er hält für jeden Knoten eine vorläufige Distanz, fixiert wiederholt den noch nicht fixierten Knoten mit der kleinsten vorläufigen Distanz und relaxiert dessen Kanten, wobei die Distanz eines Nachbarn aktualisiert wird, sobald eine kürzere Route über den aktuellen Knoten gefunden wird. Drücke oben auf Wiedergabe, um zu sehen, wie die Distanzen sinken, während jeder Knoten fixiert wird.

Die zentrale Einsicht ist gierig: Sobald der nächstgelegene, noch nicht fixierte Knoten gewählt ist, ist seine Distanz endgültig, weil jede andere Route zu ihm über einen Knoten führen müsste, der bereits weiter entfernt ist. Mit einer Prioritätswarteschlange auf Basis eines binären Heaps läuft Dijkstra in O((V + E) log V) Zeit. Er erfordert nicht negative Gewichte – verwende Bellman-Ford, wenn Kanten negativ sein können.

Zeit- und Speicherkomplexität

ImplementierungKomplexitätAnmerkungen
Binärer HeapO((V + E) log V)Die übliche, praktische Wahl
Array-DurchlaufO(V²)Einfacher; passend für dichte Graphen
SpeicherO(V)Distanzen + Prioritätswarteschlange
ErfordertNicht negative GewichteNegative Kanten brechen die gierige Wahl

Schritt für Schritt

SchrittWas passiert
1Setze die Distanz der Quelle auf 0 und alle anderen auf unendlich.
2Wähle den noch nicht fixierten Knoten mit der kleinsten vorläufigen Distanz.
3Markiere ihn als fixiert – seine kürzeste Distanz ist nun endgültig.
4Berechne für jeden Nachbarn Distanz-über-den-aktuellen + Kantengewicht.
5Ist sie kleiner als die aktuelle Distanz des Nachbarn, relaxiere sie.
6Wiederhole, bis alle erreichbaren Knoten fixiert sind.

Durchgerechnetes Beispiel

Kürzeste Wege von der Quelle A im Graphen mit den Kanten A-B=4, A-C=1, C-B=2, C-D=5, B-D=1:

SchrittFixierenDistanzenAktion
0-A=0, B=∞, C=∞, D=∞Initialisieren: Quelle A=0, alle anderen unendlich.
1A (0)B=4, C=1, D=∞Relaxiere die Kanten von A: setze B=4, C=1.
2C (1)B=3, D=6Über C: B=1+2=3 schlägt 4; D=1+5=6.
3B (3)D=4Über B: D=3+1=4 schlägt 6.
4D (4)A=0, C=1, B=3, D=4Fixiere D; nichts mehr zu relaxieren. Fertig.

Wann man den Dijkstra-Algorithmus verwendet

Verwende ihn, wennVermeide ihn, wenn
Alle Kantengewichte nicht negativ sindEine Kante negativ sein kann – verwende Bellman-Ford
Du kürzeste Wege von einer Quelle zu allen Knoten brauchstDu kürzeste Wege zwischen allen Paaren brauchst – Floyd-Warshall ist einfacher
Der Graph gewichtet ist und du exakte Distanzen willstDer Graph ungewichtet ist – reines BFS ist schneller und einfacher
Du einen guten Heap bzw. eine gute Prioritätswarteschlange hastDu ein einziges Ziel schnell mit einer Heuristik erreichen willst – verwende A*

Dijkstra's Algorithm-Code

Eine saubere, lauffähige Dijkstra's Algorithm-Implementierung in Python, JavaScript, Java, C++, C. Wähle eine Sprache, kopiere den Code oder öffne ihn vorgeladen im Coddy-Playground.

Dijkstra's Algorithm-Code in Python

Python
1import heapq2
3
4def dijkstra(graph, start):5    dist = {node: float("inf") for node in graph}6    dist[start] = 07    pq = [(0, start)]8    while pq:9        d, node = heapq.heappop(pq)10        if d > dist[node]:11            continue  # stale entry, a shorter path was already found12        for neighbor, weight in graph[node]:13            new_dist = d + weight14            if new_dist < dist[neighbor]:15                dist[neighbor] = new_dist16                heapq.heappush(pq, (new_dist, neighbor))17    return dist18
19
20graph = {21    "A": [("B", 4), ("C", 1)],22    "B": [("D", 1)],23    "C": [("B", 2), ("D", 5)],24    "D": [("E", 3)],25    "E": [],26}27
28for node, d in dijkstra(graph, "A").items():29    print(f"A -> {node}: {d}")
Führe diesen Code im Python-Playground aus

FAQ zum Dijkstra-Algorithmus

Wie hoch ist die Zeitkomplexität des Dijkstra-Algorithmus?
Mit einer Prioritätswarteschlange auf Basis eines binären Heaps läuft er in O((V + E) log V). Eine einfache Variante, die in jedem Schritt ein Array nach dem Minimum durchsucht, ist O(V²), was bei dichten Graphen sogar schneller sein kann. Beide benötigen O(V) Speicher.
Warum funktioniert Dijkstra nicht mit negativen Kantengewichten?
Dijkstra nimmt an, dass die Distanz endgültig ist, sobald der nächstgelegene, noch nicht fixierte Knoten fixiert wurde. Eine negative Kante könnte später einen kürzeren Weg zu einem bereits fixierten Knoten schaffen und diese Annahme brechen. Für Graphen mit negativen Gewichten verwende den Bellman-Ford-Algorithmus.
Was ist der Unterschied zwischen Dijkstra und BFS?
BFS findet kürzeste Wege durch Zählen der Kanten (jedes Kantengewicht ist praktisch 1) mit einer einfachen Warteschlange. Dijkstra verallgemeinert dies auf gewichtete Graphen, indem stets der Knoten mit der kleinsten Gesamtdistanz mithilfe einer Prioritätswarteschlange expandiert wird. In einem ungewichteten Graphen liefern beide dieselben Wege.
Was ist der Unterschied zwischen Dijkstra und der A*-Suche?
A* ist Dijkstra plus einer Heuristik, die die verbleibende Distanz zu einem Ziel schätzt und die Suche so auf dieses Ziel lenkt, statt sich gleichmäßig in alle Richtungen auszubreiten. Ist die Heuristik null, entartet A* genau zu Dijkstra. Verwende A*, wenn du ein einziges Ziel und eine gute zulässige Heuristik hast; verwende Dijkstra, wenn du Distanzen zu allen Knoten brauchst.
Wann sollte ich Dijkstra statt Bellman-Ford verwenden?
Verwende Dijkstra immer dann, wenn alle Kantengewichte nicht negativ sind – er ist schneller mit O((V + E) log V) gegenüber O(V·E) bei Bellman-Ford. Wähle Bellman-Ford nur, wenn Kanten negativ sein können oder du negative Zyklen erkennen musst. Bei nicht negativen Graphen ist Dijkstra fast immer die bessere Wahl.
Kann Dijkstra einen Knoten erneut besuchen, nachdem er fixiert wurde?
Nein – sobald ein Knoten fixiert ist, ist seine Distanz endgültig und wird nie wieder relaxiert. Eine häufige Falle bei Heap-Implementierungen ist es, veraltete Einträge in der Prioritätswarteschlange zu belassen, nachdem sich die Distanz eines Knotens verbessert hat; du musst einen entnommenen Knoten überspringen, wenn er bereits fixiert ist (seine entnommene Distanz übersteigt die gespeicherte Distanz). Diese Prüfung zu vergessen liefert weiterhin korrekte Antworten, verschwendet aber Arbeit.
Coddy programming languages illustration

Meistere Algorithmen mit Coddy

LOS GEHT'S