Ein Graph G = (V, E) besteht aus einer Menge V von Knoten und einer Menge E von Kanten. Die Kanten sind Verbindungen zwischen den Knoten; sie können gerichtet oder ungerichtet sein. Graphen werden in vielen Anwendungsgebieten zur Modellierung von Problemen verwendet.
Als Beispiel zeigt Bild 1 einen Graphen G.
Bild 1: Graph G
Die im Folgenden angegebenen Möglichkeiten zur Implementierung eines Graphen als Datenstruktur basieren auf einer abstrakten Klasse Graph, die grundlegende Daten und Methoden zur Verfügung stellt.
Eine einfache Möglichkeit zur konkreten Implementierung eines Graphen besteht darin, die Kanten des Graphen in Form einer Adjazenzmatrix darzustellen.
Definition: Sei G = (V, E) ein Graph mit V = {0, ..., n-1}, n ∈ ℕ. Die Adjazenzmatrix des Graphen ist eine boolesche n × n-Matrix A, für die gilt
Ai,j = |
|
für alle i, j ∈ V.
Beispiel: Adjazenzmatrix des Graphen G aus Bild 1 (leere Einträge = false, 1 = true)
0 | 1 | 2 | 3 | 4 | |
---|---|---|---|---|---|
0 | 1 | 1 | |||
1 | 1 | ||||
2 | 1 | ||||
3 | 1 | ||||
4 |
Es folgt eine entsprechende Implementierung des Graphen in der Klasse DirectedGraph, die von der abstrakten Klasse Graph mit Typ-Parameter Boolean abgeleitet ist.
Ein ungerichteter Graph lässt sich als gerichteter Graph, dessen Kantenrelation symmetrisch ist, ansehen, also als Spezialfall eines gerichteten Graphen. Entsprechend modellieren wir ungerichtete Graphen, indem wir die Klasse UndirectedGraph von DirectedGraph ableiten und nur die Methode setWeight in der Weise überschreiben, dass mit jeder Kante (i, j) auch die Kante (j, i) erzeugt wird.
Eine Adjazenzliste ist eine Liste aller Knoten, zu denen von einem bestimmten Knoten aus eine Kante hinführt. Um einen Graphen darzustellen wird also für jeden seiner Knoten eine Adjazenzliste benötigt.
Beispiel: Der Graph G aus Bild 1 lässt sich durch folgende Adjazenzlisten seiner Knoten 0, ..., 4 darstellen:
0 | 1 | 2 |
---|---|---|
1 | 2 | |
2 | 0 | |
3 | 0 | |
4 |
Aus dieser Darstellung geht hervor, dass vom Knoten 0 aus Kanten zu den Knoten 1 und 2 hinführen, vom Knoten 1 aus eine Kante zum Knoten 2, vom Knoten 2 zum Knoten 0 usw.
Es bietet sich an, die Adjazenzlisten als ArrayList zu implementieren. Als NeighbourIterator kann dann der Standard-Iterator des Typs ArrayList verwendet werden.
Aufgabe 1: Programmieren Sie eine entsprechende Implementierung des Graphen als Klasse DirectedGraph1, abgeleitet von der abstrakten Klasse Graph. Stellen Sie die Adjazenzlisten durch Objekte vom Typ ArrayList mit Typ-Parameter Integer dar. Implementieren Sie die abstrakten Methoden der abstrakten Klasse Graph.
Weiter mit: [Graphen mit Kantenmarkierungen] oder [up]