Stark zusammenhängende Komponenten mit Kosaraju
Führen Sie DFS auf dem ursprünglichen Graphen aus, um die Abschlussreihenfolge zu erhalten, transponieren Sie den Graphen und führen Sie DFS erneut in umgekehrter Abschlussreihenfolge aus, um SCCs zu identifizieren.
Stark zusammenhängende Komponenten mit Kosaraju ist eine kostenlose Coding Interview Prep-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Coding Interview Prep-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Coding Interview Prep-Kurs umfasst insgesamt 4 Lektionen.
Stark zusammenhängende Komponenten definiert
Eine stark zusammenhängende Komponente (SCC) eines gerichteten Graphen ist eine maximale Menge von Knoten, sodass es von jedem Knoten zu jedem anderen Knoten innerhalb dieser Menge einen Pfad gibt. Wenn beispielsweise die Knoten A, B und C einen Zyklus bilden (A→B→C→A), gehören sie alle zur selben SCC. Ein einzelner Knoten ohne Selbstschleife bildet seine eigene SCC. SCCs machen die zyklische Struktur eines gerichteten Graphen sichtbar.
Kosarajus Algorithmus: Zwei DFS-Durchläufe
Kosarajus Algorithmus findet alle SCCs in O(V + E) mit zwei DFS-Durchläufen. Durchlauf 1: Führen Sie DFS auf dem ursprünglichen Graphen aus und legen Sie die Knoten in der Reihenfolge ihres Abschlusses (Postorder) auf einen Stack. Durchlauf 2: Führen Sie DFS auf dem transponierten (umgekehrten) Graphen aus und verarbeiten Sie die Knoten in umgekehrter Abschlussreihenfolge (indem Sie sie vom Stack nehmen). Jeder DFS-Baum im zweiten Durchlauf entspricht einer SCC.
Warum Kosaraju funktioniert
Im ersten Durchlauf ist die SCC, deren DFS-Baum zuletzt abgeschlossen wird, diejenige ohne ausgehende Kanten zu anderen SCCs (eine „Senken“-SCC im Kondensations-DAG). Im transponierten Graphen hat diese SCC keine eingehenden Kanten von anderen SCCs — daher bleibt eine von ihr ausgehende DFS im zweiten Durchlauf auf diese SCC beschränkt. Jede nachfolgende DFS im zweiten Durchlauf bleibt innerhalb ihrer eigenen SCC, weil alle Kanten zwischen SCCs umgekehrt wurden und nun zu bereits besuchten SCCs führen.
Durchlauf 1: Abschlussreihenfolge erstellen
Führen Sie DFS auf dem ursprünglichen Graphen aus und legen Sie jeden Knoten nach seinem Abschluss auf einen Stack (Postorder). In diesem Durchlauf interessieren uns die Komponenten nicht — nur die Abschlussreihenfolge. Der zuletzt abgeschlossene Knoten befindet sich in einer „Quellen“-SCC des Kondensations-DAG.
from collections import defaultdict
def kosaraju(n, edges):
graph = defaultdict(list)
rev_graph = defaultdict(list)
for u, v in edges:
graph[u].append(v)
rev_graph[v].append(u) # reversed edges
visited = set()
finish_stack = []
def dfs1(node):
visited.add(node)
for nxt in graph[node]:
if nxt not in visited:
dfs1(nxt)
finish_stack.append(node) # push after all neighbours done
for i in range(n):
if i not in visited:
dfs1(i)
return finish_stack, rev_graphDurchlauf 2: DFS auf dem transponierten Graphen
Nehmen Sie die Knoten aus dem Abschluss-Stack (zuerst die mit der größten Abschlusszeit) und führen Sie DFS auf dem transponierten Graphen aus. Jede DFS von einem unbesuchten Knoten entdeckt genau eine SCC. Markieren Sie alle Knoten, die bei dieser DFS erreicht werden, als zu derselben Komponente gehörig.
from collections import defaultdict
def kosaraju_full(n, edges):
graph = defaultdict(list)
rev_graph = defaultdict(list)
for u, v in edges:
graph[u].append(v)
rev_graph[v].append(u)
visited = set()
finish_stack = []
def dfs1(node):
visited.add(node)
for nxt in graph[node]:
if nxt not in visited: dfs1(nxt)
finish_stack.append(node)
for i in range(n):
if i not in visited: dfs1(i)
visited.clear()
sccs = []
def dfs2(node, component):
visited.add(node)
component.append(node)
for nxt in rev_graph[node]:
if nxt not in visited: dfs2(nxt, component)
while finish_stack:
node = finish_stack.pop()
if node not in visited:
component = []
dfs2(node, component)
sccs.append(component)
return sccs
# Graph with SCCs: {0,1,2} and {3}
edges = [(0,1),(1,2),(2,0),(1,3)]
print(kosaraju_full(4, edges)) # [[3], [0,2,1]] or similarDen Graphen transponieren
Der transponierte Graph kehrt jede Kante um: Wenn der ursprüngliche Graph u → v enthält, enthält die Transposition v → u. Die Transposition bewahrt die SCCs — wenn A und B im ursprünglichen Graphen zur selben SCC gehören, gehören sie auch in der Transposition zur selben SCC (da alle Pfade umgekehrt werden, die Knoten aber weiterhin verbinden). Wenn Sie die Transposition bereits beim Einlesen der Eingaben erstellen (wie oben gezeigt), entfällt ein separater Transpositionsschritt.
Iterative Version für große Graphen
Bei großen Graphen ersetzen Sie rekursive DFS durch iterative DFS mit einem expliziten Stack, um Pythons Rekursionslimit zu vermeiden. Die iterative Variante legt Knoten auf den Stack, verarbeitet sie und verwaltet eine separate „return“-Markierung, um die Postorder zu simulieren.
def dfs1_iterative(start, graph, visited, finish_stack):
stack = [(start, iter(graph[start]))]
visited.add(start)
while stack:
node, neighbours = stack[-1]
try:
nxt = next(neighbours)
if nxt not in visited:
visited.add(nxt)
stack.append((nxt, iter(graph[nxt])))
except StopIteration:
stack.pop()
finish_stack.append(node)
print('Iterative DFS for large graphs avoids recursion limit')Tarjans Algorithmus: Alternative für SCCs
Tarjans Algorithmus findet SCCs in einem einzigen DFS-Durchlauf (im Vergleich zu den zwei Durchläufen von Kosaraju). Dabei verwaltet er einen Stack mit Knoten und weist jedem Knoten eine Entdeckungszeit und einen Low-Link-Wert zu. Wenn die Entdeckungszeit eines Knotens seinem Low-Link-Wert entspricht, ist er die Wurzel einer SCC. Tarjans Algorithmus ist etwas komplexer zu implementieren, vermeidet jedoch das Erstellen des transponierten Graphen. Beide Verfahren haben die Komplexität O(V + E).
Anwendungen von SCCs
SCCs werden verwendet für: (1) Compiler-Optimierung — zum Identifizieren gegenseitig rekursiver Funktionen. (2) Analyse sozialer Netzwerke — zum Finden eng vernetzter Gemeinschaften. (3) 2-SAT-Problem — zum Bestimmen der Erfüllbarkeit von Klauseln mit zwei Literalen. (4) Web-Crawling — zum Identifizieren von Seiten-Clustern mit vielen Querverweisen. (5) Kondensations-DAG — nach dem Finden der SCCs ist die Kondensation des Graphen ein DAG, der eine topologische Analyse zyklischer Graphen ermöglicht.
Kondensations-DAG
Die Kondensation eines gerichteten Graphen fasst jede SCC zu einem einzelnen Knoten zusammen und fügt eine Kante zwischen zwei Superknoten hinzu, wenn eine Kante zwischen ihren zugehörigen SCCs existiert. Das Ergebnis ist immer ein DAG — Sie können darauf eine topologische Sortierung ausführen. Dadurch können Algorithmen, die nur auf DAGs funktionieren (wie DP), auf beliebige gerichtete Graphen angewendet werden, indem Sie mit deren Kondensation arbeiten.
def build_condensation(n, edges, sccs):
# Assign each node to its SCC index
scc_id = [0] * n
for idx, component in enumerate(sccs):
for node in component:
scc_id[node] = idx
# Build condensation edges
condensation_edges = set()
for u, v in edges:
su, sv = scc_id[u], scc_id[v]
if su != sv:
condensation_edges.add((su, sv))
return list(condensation_edges)
edges = [(0,1),(1,2),(2,0),(1,3)]
sccs = [[3],[0,1,2]]
print(build_condensation(4, edges, sccs)) # [(0,1)] or [(1,0)]Anzahl der SCCs und Grapheneigenschaften
Die Anzahl der SCCs in einem gerichteten Graphen gibt Aufschluss über seine zyklische Struktur. Ein DAG hat n SCCs (jeder Knoten ist seine eigene SCC). Ein stark zusammenhängender Graph hat genau 1 SCC. Allgemein bilden die SCCs nach ihrer Zusammenfassung einen DAG — die Kondensation. Wenn der Kondensations-DAG eine eindeutige Quelle (Knoten mit Eingangsgrad 0) und eine eindeutige Senke (Knoten mit Ausgangsgrad 0) besitzt, gelten bestimmte Zusammenhangseigenschaften. Diese Eigenschaften werden in Aufgaben zur Erreichbarkeit nach dem Hinzufügen einer minimalen Anzahl von Kanten geprüft.
Schnelltest
Überprüfen Sie Ihr Verständnis der Konzepte von Data Structures & Algorithms — Coding Interview Prep aus dieser Lektion.
Zusammenfassung der Lektion
In dieser Lektion haben Sie gelernt: SCCs sind maximale Mengen, in denen jeder Knoten von jedem anderen aus erreichbar ist, Kosaraju verwendet zwei DFS-Durchläufe — zunächst auf dem ursprünglichen Graphen zur Bestimmung der Abschlussreihenfolge, danach auf dem transponierten Graphen und die Kondensation jedes gerichteten Graphen ist ein DAG, der für weitere Analysen verwendet werden kann. Als Nächstes erstellen wir TrieNode-Datenstrukturen für Einfüge-, Such- und Präfixoperationen.
Lerne Coding Interview Prep mit einem KI-Tutor — kostenlos
Schreibe und führe echten Code in deinem Browser aus, bekomme sofortige Hilfe von einem 24/7 KI-Tutor und setze dein Lernen im Web oder in der App fort.
- Kurse
- 90
- Lektionen
- 360
Häufig gestellte Fragen
Ist die Lektion „Stark zusammenhängende Komponenten mit Kosaraju“ kostenlos?
Ja — der vollständige Text von „Stark zusammenhängende Komponenten mit Kosaraju“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Coding Interview Prep-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Coding Interview Prep-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Stark zusammenhängende Komponenten mit Kosaraju“?
Führen Sie DFS auf dem ursprünglichen Graphen aus, um die Abschlussreihenfolge zu erhalten, transponieren Sie den Graphen und führen Sie DFS erneut in umgekehrter Abschlussreihenfolge aus, um SCCs zu… Du übst Coding Interview Prep mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Coding Interview Prep zu starten?
Keine Vorkenntnisse erforderlich. Coding Interview Prep auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.
Wie lange dauert die Lektion „Stark zusammenhängende Komponenten mit Kosaraju“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Coding Interview Prep-Lektion Code schreiben und ausführen?
Ja. Jede Coding Interview Prep-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Kahns Algorithmus: Topologische Sortierung mit BFS
- Topologische Sortierung per DFS-Postorder
- Course Schedule I und II
- Stark zusammenhängende Komponenten mit Kosaraju