Zuletzt aktualisiert am 16.12.2025 6 Minuten Lesezeit

Graph

Ein Graph ist eine fundamentale Datenstruktur in der Informatik, die aus einer Menge von Knoten (Vertices) und Kanten (Edges) besteht. Graphen modellieren Beziehungen zwischen Objekten und sind unverzichtbar für die Lösung komplexer Probleme wie Routenplanung, Netzwerkanalyse oder Abhängigkeitsauflösung.

Formal definiert ist ein Graph G = (V, E), wobei V die Menge der Knoten und E die Menge der Kanten bezeichnet. Diese abstrakte Struktur ermöglicht es, reale Zusammenhänge wie soziale Netzwerke, Straßenkarten oder Computernetze mathematisch zu beschreiben und algorithmisch zu verarbeiten.

Grundlegende Konzepte

Um mit Graphen arbeiten zu können, musst du einige zentrale Begriffe verstehen:

Knoten und Kanten

Knoten (Vertices) repräsentieren die Objekte oder Entitäten in einem Graphen – beispielsweise Städte auf einer Landkarte, Personen in einem sozialen Netzwerk oder Router in einem Computernetzwerk. Kanten (Edges) stellen die Verbindungen oder Beziehungen zwischen diesen Knoten dar, etwa Straßen zwischen Städten oder Freundschaften zwischen Personen.

Wichtige Begriffe:

  • Adjazent: Zwei Knoten sind adjazent (benachbart), wenn eine Kante sie direkt verbindet
  • Grad eines Knotens: Die Anzahl der Kanten, die mit dem Knoten verbunden sind
  • Pfad: Eine Folge von Knoten, die durch Kanten verbunden sind
  • Zyklus: Ein Pfad, der zum Ausgangsknoten zurückführt

Gerichtete vs. ungerichtete Graphen

Bei ungerichteten Graphen haben Kanten keine Richtung – eine Verbindung zwischen A und B kann in beide Richtungen durchlaufen werden. Ein typisches Beispiel ist ein Freundschaftsnetzwerk: Wenn Anna mit Bob befreundet ist, ist auch Bob mit Anna befreundet.

Gerichtete Graphen (auch Digraphen genannt) haben Kanten mit einer festgelegten Richtung. Eine Kante von A nach B bedeutet nicht automatisch, dass es auch eine Kante von B nach A gibt. Beispiele sind Einbahnstraßen oder Follower-Beziehungen auf Social-Media-Plattformen.

Typ Kantenform Beispiel
Ungerichtet Ungeordnetes Paar {u, v} Freundschaftsnetzwerk
Gerichtet (Digraph) Geordnetes Paar (u, v) Twitter-Follower, Einbahnstraßen

Gewichtete Graphen

In gewichteten Graphen hat jede Kante einen numerischen Wert (Gewicht), der zusätzliche Informationen wie Entfernung, Kosten, Kapazität oder Zeitdauer repräsentiert. Bei Navigationssystemen beispielsweise können die Gewichte die Streckenlänge in Kilometern oder die geschätzte Fahrtzeit darstellen.

Wichtige Graphenarten

Baum

Ein Baum ist ein zusammenhängender, ungerichteter Graph ohne Zyklen. Jeder Knoten (außer der Wurzel) hat genau einen Vorgänger, und zwischen zwei beliebigen Knoten existiert genau ein Pfad. Bäume sind fundamental für Datenstrukturen wie Binärbäume, Heaps oder Dateisysteme.

DAG – Directed Acyclic Graph

Ein DAG (gerichteter azyklischer Graph) ist ein gerichteter Graph, der keine Zyklen enthält. DAGs sind besonders wichtig für Abhängigkeitsbeziehungen: Build-Systeme wie Maven oder Gradle nutzen sie, um die Reihenfolge von Kompilierungsschritten zu bestimmen. Auch Git-Commits bilden einen DAG.

Vollständiger Graph

In einem vollständigen Graphen ist jeder Knoten mit jedem anderen Knoten verbunden. Ein vollständiger Graph mit n Knoten hat n(n-1)/2 Kanten bei ungerichteten bzw. n(n-1) Kanten bei gerichteten Graphen.

Darstellungsformen

Für die Implementierung von Graphen in Programmen gibt es zwei gängige Darstellungsformen, die je nach Anwendungsfall Vor- und Nachteile bieten.

Adjazenzmatrix

Eine Adjazenzmatrix ist eine n×n-Matrix, wobei n die Anzahl der Knoten ist. Der Eintrag an Position [i][j] gibt an, ob eine Kante zwischen Knoten i und j existiert (1 oder das Kantengewicht) oder nicht (0).

// Beispiel: Ungerichteter Graph mit 4 Knoten
// Kanten: (0,1), (0,2), (1,2), (2,3)

    0  1  2  3
0 [ 0, 1, 1, 0 ]
1 [ 1, 0, 1, 0 ]
2 [ 1, 1, 0, 1 ]
3 [ 0, 0, 1, 0 ]

Eigenschaften der Adjazenzmatrix:

  • Speicherbedarf: O(n²)
  • Prüfung auf Kantexistenz: O(1)
  • Alle Nachbarn finden: O(n)
  • Gut geeignet für dichte Graphen (viele Kanten)

Adjazenzliste

Eine Adjazenzliste speichert für jeden Knoten eine Liste seiner Nachbarn. Diese Darstellung ist speichereffizienter bei dünn besetzten Graphen (wenige Kanten im Verhältnis zur Knotenanzahl).

// Gleicher Graph als Adjazenzliste
0: [1, 2]
1: [0, 2]
2: [0, 1, 3]
3: [2]

Eigenschaften der Adjazenzliste:

  • Speicherbedarf: O(n + m) mit m = Anzahl Kanten
  • Prüfung auf Kantexistenz: O(Grad des Knotens)
  • Alle Nachbarn finden: O(Grad des Knotens)
  • Gut geeignet für dünn besetzte Graphen

Wichtige Graphenalgorithmen

Breitensuche (BFS)

Die Breitensuche (Breadth-First Search) erkundet den Graphen schichtweise von einem Startknoten aus. Sie besucht zuerst alle direkten Nachbarn, dann deren Nachbarn und so weiter. BFS verwendet eine Queue (Warteschlange) und findet in ungewichteten Graphen den kürzesten Pfad.

void bfs(Graph g, int start) {
    boolean[] visited = new boolean[g.vertices];
    Queue<Integer> queue = new LinkedList<>();

    visited[start] = true;
    queue.add(start);

    while (!queue.isEmpty()) {
        int current = queue.poll();
        System.out.print(current + " ");

        for (int neighbor : g.adjList[current]) {
            if (!visited[neighbor]) {
                visited[neighbor] = true;
                queue.add(neighbor);
            }
        }
    }
}
// Laufzeit: O(V + E)

Tiefensuche (DFS)

Die Tiefensuche (Depth-First Search) geht so weit wie möglich in die Tiefe, bevor sie zurückkehrt und andere Pfade erkundet. Sie kann rekursiv oder mit einem Stack implementiert werden und eignet sich besonders für Zykluserkennung, topologische Sortierung und das Finden von Zusammenhangskomponenten.

void dfs(Graph g, int v, boolean[] visited) {
    visited[v] = true;
    System.out.print(v + " ");

    for (int neighbor : g.adjList[v]) {
        if (!visited[neighbor]) {
            dfs(g, neighbor, visited);
        }
    }
}
// Laufzeit: O(V + E)

Dijkstra-Algorithmus

Der Dijkstra-Algorithmus findet den kürzesten Pfad von einem Startknoten zu allen anderen Knoten in einem gewichteten Graphen mit nicht-negativen Kantengewichten. Er verwendet eine Prioritätswarteschlange und wählt immer den noch nicht besuchten Knoten mit der geringsten Distanz.

Funktionsweise:

  1. Setze die Distanz zum Startknoten auf 0, alle anderen auf unendlich
  2. Füge den Startknoten in die Prioritätswarteschlange ein
  3. Wiederhole: Nimm den Knoten mit minimaler Distanz heraus
  4. Aktualisiere die Distanzen aller Nachbarn (Relaxation)
  5. Ende, wenn alle Knoten besucht wurden

Laufzeit: O((V + E) log V) mit Heap-Implementierung

Praktische Anwendungen

Graphen sind in nahezu jedem Bereich der Informatik und darüber hinaus unverzichtbar:

Soziale Netzwerke

  • Knoten: Nutzerprofile
  • Kanten: Freundschaften, Follower-Beziehungen
  • Anwendung: Freundesvorschläge, Influencer-Erkennung, Community-Detection

Navigation und Routenplanung

  • Knoten: Kreuzungen, Orte
  • Kanten: Straßen, Verbindungen (gewichtet nach Entfernung/Zeit)
  • Anwendung: Google Maps, Navigationssysteme, Logistikoptimierung

Netzwerk-Routing

  • Knoten: Router, Server
  • Kanten: Netzwerkverbindungen (gewichtet nach Latenz, Bandbreite)
  • Anwendung: OSPF-Routing-Protokoll, Netzwerkdiagnose

Software-Entwicklung

  • Abhängigkeitsgraphen in Build-Systemen (Maven, Gradle, npm)
  • Versionskontrolle (Git-Commit-Historie)
  • Call-Graphs für Codeanalyse

Zeitkomplexität der Operationen

Die Zeitkomplexität von Graphoperationen hängt von der gewählten Darstellungsform ab:

Operation Adjazenzmatrix Adjazenzliste
Kante hinzufügen O(1) O(1)
Kante entfernen O(1) O(V)
Kante prüfen O(1) O(V)
Alle Nachbarn O(V) O(Grad)
Speicherbedarf O(V²) O(V + E)
BFS/DFS O(V²) O(V + E)

Graphen in der IT-Ausbildung

Für Fachinformatiker Anwendungsentwicklung sind Graphen ein wichtiges Thema in der IHK-Prüfung. Du solltest die grundlegenden Konzepte, Darstellungsformen und mindestens BFS sowie DFS implementieren können. Auch Fachinformatiker Systemintegration begegnen Graphen im Kontext von Netzwerktopologien und Routing.

Quellen und weiterführende Links