Menu
Coddy logo textTech

Tiefensuche (DFS)

Zuletzt aktualisiert

Die Tiefensuche erkundet einen Graphen, indem sie entlang jedes Zweigs so tief wie möglich geht, bevor sie zurückgeht. Ausgehend von einem Startknoten besucht sie einen Nachbarn, dann dessen Nachbarn und so weiter, bis sie in eine Sackgasse gerät (ein Knoten ohne unbesuchte Nachbarn); dann geht sie zurück und probiert den nächsten Zweig. Drücke oben auf Abspielen, um zu sehen, wie sie einen Pfad hinabsteigt, den Grund erreicht und wieder herauskommt.

DFS lässt sich natürlich mit einem Stapel ausdrücken - entweder einem expliziten Stapel (wie hier animiert) oder dem Aufrufstapel über Rekursion. Sie besucht jeden Knoten und jede Kante einmal und läuft daher in O(V + E) Zeit für einen Graphen mit V Knoten und E Kanten.

Zeit- und Speicherkomplexität

MaßKomplexitätAnmerkungen
ZeitO(V + E)Jeder Knoten und jede Kante einmal besucht
SpeicherO(V)Stapel + Besucht-Menge, im schlimmsten Fall alle Knoten
TraversierungTiefstes zuerstFolgt einem Zweig bis zum Ende vor den anderen
DatenstrukturStapel (oder Rekursion)Die LIFO-Reihenfolge treibt das Tiefenverhalten an

Schritt für Schritt

SchrittWas passiert
1Lege den Startknoten auf den Stapel.
2Nimm einen Knoten herunter; wenn bereits besucht, überspringe ihn.
3Markiere ihn als besucht und notiere die Kante, die ihn erreicht hat.
4Lege alle seine unbesuchten Nachbarn auf den Stapel.
5Wiederhole, bis der Stapel leer ist.

Durchgerechnetes Beispiel

Iteratives DFS ab A im Graphen A → [B, C], B → [D], C → [E], wobei Nachbarn in der aufgeführten Reihenfolge abgelegt werden (der LIFO-Stapel nimmt das zuletzt Abgelegte zuerst herunter):

SchrittStapel (oben rechts)BesuchtAktion
1[A]{}Lege die Quelle A ab.
2[B, C]{A}Nimm A herunter, markiere besucht, lege Nachbarn B dann C ab.
3[B, E]{A, C}Nimm C herunter, markiere besucht, lege Nachbar E ab.
4[B]{A, C, E}Nimm E herunter, markiere besucht, keine Nachbarn.
5[D]{A, C, E, B}Nimm B herunter, markiere besucht, lege Nachbar D ab.
6[]{A, C, E, B, D}Nimm D herunter, markiere besucht, Stapel leer: fertig.

Wann man DFS verwendet

Verwenden, wennVermeiden, wenn
Du Zykluserkennung, topologische Sortierung oder das Finden von Zusammenhangskomponenten brauchst.Du den kürzesten Pfad in einem ungewichteten Graphen brauchst - das leistet BFS, nicht DFS.
Der Graph breit und flach ist, sodass ein Stapel weit weniger Speicher braucht als eine Warteschlange mit vielen Randknoten.Der Graph sehr tief ist und du Rekursion verwendest - der Aufrufstapel kann überlaufen.
Du Pfade erschöpfend erkunden willst, etwa beim Lösen von Labyrinthen oder bei der Suche mit Backtracking.Du Knoten in der Reihenfolge ihrer Entfernung von der Quelle entdecken musst.
Du Erreichbarkeit prüfst oder ob ein Pfad zwischen zwei Knoten existiert.Du die minimale Anzahl an Kanten auf dem gefundenen Pfad garantieren musst.

Depth-First Search-Code

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

Depth-First Search-Code in Python

Python
1def dfs(graph, node, visited):2    visited.add(node)3    order = [node]4    for neighbor in graph[node]:5        if neighbor not in visited:6            order.extend(dfs(graph, neighbor, visited))7    return order8
9
10graph = {11    "A": ["B", "C"],12    "B": ["D", "E"],13    "C": ["F"],14    "D": [],15    "E": ["F"],16    "F": [],17}18
19order = dfs(graph, "A", set())20print("DFS order:", " -> ".join(order))
Führe diesen Code im Python-Playground aus

Häufige Fragen zur Tiefensuche

Wie hoch ist die Zeitkomplexität von DFS?
DFS läuft in O(V + E) Zeit, wobei V die Anzahl der Knoten und E die Anzahl der Kanten ist, weil sie jeden Knoten einmal besucht und jede Kante einmal betrachtet. Sie benötigt O(V) Speicher für den Stapel und die Besucht-Menge.
Was ist der Unterschied zwischen DFS und BFS?
DFS verwendet einen Stapel und taucht entlang eines Zweigs tief ein, bevor sie zurückgeht, während BFS eine Warteschlange verwendet und Ebene für Ebene erkundet, die nächstgelegenen Knoten zuerst. BFS findet den kürzesten Pfad in einem ungewichteten Graphen; DFS nicht, aber sie verbraucht bei breiten Graphen weniger Speicher und ist für Aufgaben wie Zykluserkennung und topologische Sortierung naheliegend.
Ist DFS rekursiv oder iterativ?
Beides funktioniert. Die rekursive Variante nutzt implizit den Aufrufstapel des Programms und ist sehr kompakt; die iterative Variante nutzt einen expliziten Stapel (wie die Animation hier) und vermeidet Stapelüberläufe durch tiefe Rekursion bei großen Graphen.
Wann sollte ich DFS statt BFS verwenden?
Verwende DFS, wenn du ganze Pfade erkunden musst: Zykluserkennung, topologische Sortierung, Zusammenhangskomponenten oder Suche mit Backtracking wie beim Lösen eines Labyrinths. Sie verbraucht außerdem bei breiten Graphen weniger Speicher, da der Stapel jeweils nur die Grenze eines Zweigs hält. Greife zu BFS, wenn du den kürzesten Pfad in einem ungewichteten Graphen oder Knoten in der Reihenfolge ihrer Entfernung von der Quelle brauchst.
Kann DFS den kürzesten Pfad finden?
Nicht zuverlässig. DFS gibt den ersten Pfad zurück, den sie zufällig findet, der oft nicht der mit den wenigsten Kanten ist, weil sie sich darauf festlegt, tief einzutauchen, statt sich gleichmäßig auszubreiten. Für kürzeste Pfade in einem ungewichteten Graphen verwende BFS, und für gewichtete Graphen den Dijkstra-Algorithmus.
Warum braucht DFS eine Besucht-Menge?
Ohne eine Besucht-Menge besucht DFS Knoten, die über mehrere Pfade erreichbar sind, erneut und läuft in einem zyklischen Graphen endlos. Einen Knoten beim Herunternehmen als besucht zu markieren (und bereits besuchte Herunternahmen zu überspringen) garantiert, dass jeder Knoten einmal verarbeitet wird, und hält die Laufzeit bei O(V + E). Ein häufiger Fehler ist, Knoten erst beim Herunternehmen als besucht zu markieren und trotzdem Duplikate abzulegen; das ist korrekt, kann aber veraltete Einträge auf dem Stapel hinterlassen, die übersprungen werden müssen.
Coddy programming languages illustration

Meistere Algorithmen mit Coddy

LOS GEHT'S