Gliederung. 5. Compiler. 6. Sortieren und Suchen. 7. Graphen

Ähnliche Dokumente
Gliederung. 5. Compiler. 6. Sortieren und Suchen. 7. Graphen

Gliederung. Algorithmen und Datenstrukturen II. ADT Graph. ADT Graph. Graphen in JAVA. Klasse Graph Suche Breitensuche Tiefensuche. D.

Programmiertechnik II

Programmiertechnik II

Algorithmen und Datenstrukturen SS09. Foliensatz 16. Michael Brinkmeier. Technische Universität Ilmenau Institut für Theoretische Informatik

Programm heute. Algorithmen und Datenstrukturen (für ET/IT) Übersicht: Graphen. Definition: Ungerichteter Graph. Definition: Ungerichteter Graph

ADS: Algorithmen und Datenstrukturen 2

Graphen Jiri Spale, Algorithmen und Datenstrukturen - Graphen 1

Kapitel 5: Graphen und Graphalgorithmen

Einführung in die Informatik 2

Graphenalgorithmen I

Wir nennen einen Pfad in einem gerichteten Graphen Zyklus, wenn der Pfad im gleichen Knoten beginnt und endet, d. h.

ADS: Algorithmen und Datenstrukturen 2

Informatik II, SS 2018

ADS 2: Algorithmen und Datenstrukturen

Routing A lgorithmen Algorithmen Begriffe, Definitionen Wegewahl Verkehrslenkung

Routing Algorithmen. Begriffe, Definitionen

Informatik II, SS 2014

ADS: Algorithmen und Datenstrukturen 2

Einheit 11 - Graphen

ADS: Algorithmen und Datenstrukturen 2

10 Graphenalgorithmen in Java

Programmierkurs Python II

Gliederung. 5. Compiler. 6. Sortieren und Suchen. 7. Graphen

Verkettete Datenstrukturen: Bäume

Algorithmen und Datenstrukturen (ESE) Entwurf, Analyse und Umsetzung von Algorithmen (IEMS) WS 2013 / 2014 Vorlesung 12, Donnerstag, 23.

Programmierkurs Python

Hallo Welt für Fortgeschrittene

Einführung in die Informatik 2

Informatik II, SS 2016

Algorithmen und Datenstrukturen 2

Diskrete Strukturen WS 2005/06. Ernst W. Mayr. 27. Januar Fakultät für Informatik TU München

Kodieren Von Graphen

B-Bäume, speziell (2,4)-Bäume / Externe Suche: BBaum- Varianten 5.7 (Rot-Schwarz-Bäume) 5.8 Streuspeicherverfahren (Hash-Verfahren)

Datenstrukturen Teil 2. Bäume. Definition. Definition. Definition. Bäume sind verallgemeinerte Listen. Sie sind weiter spezielle Graphen

Graphalgorithmen. Graphen

Algorithmen und Datenstrukturen (ESE) Entwurf, Analyse und Umsetzung von Algorithmen (IEMS) WS 2014 / 2015 Vorlesung 12, Donnerstag, 22.

Teil 2: Graphenalgorithmen

Lernmodul 7 Algorithmus von Dijkstra

Graphalgorithmen I. Simon Regnet. May 16, Universität Erlangen. Simon Regnet (Universität Erlangen) Graphalgorithmen I May 16, / 56

Gliederung. 5. Compiler. 6. Sortieren und Suchen. 7. Graphen

Graphenalgorithmen I. Geschickt Programmieren für den ICPC- Wettbewerb. Felix Weissenberger

Informatik II, SS 2016

Informatik II, SS 2016

Folien aus der Vorlesung Optimierung I SS2013

Wintersemester 2004/ Januar Aus der Vorlesung sind Datenstrukturen zur Repräsentation von Wäldern disjunkter Mengen bekannt.

Algorithmen und Datenstrukturen 13

Vorlesung Datenstrukturen

Definition Gerichteter Pfad. gerichteter Pfad, wenn. Ein gerichteter Pfad heißt einfach, falls alle u i paarweise verschieden sind.

Algorithmen und Datenstrukturen II

10. Übungsblatt zu Algorithmen I im SS 2010

Algorithmen I. Tutorium 1-8. Sitzung. Dennis Felsing

Graphen. Anwendung, Repräsentation, Tiefensuche, Breitensuche, Warshall s Algorithmus, kürzeste Wege.

Dabei handelt es sich um eine Tabelle, in der die Zeilen- und Spaltenüberschriften die Knotenbezeichner sind.

Algorithmen und Datenstrukturen

Theoretische Informatik 1 WS 2007/2008. Prof. Dr. Rainer Lütticke

5 Graphen. Repräsentationen endlicher Graphen. 5.1 Gerichtete Graphen. 5.2 Ungerichtete Graphen. Ordnung von Graphen

Algorithmen und Datenstrukturen II

Graphdurchmusterung, Breiten- und Tiefensuche

8. Übung zu Algorithmen I 15. Juni 2016

VL-14: Graphalgorithmen I. (Datenstrukturen und Algorithmen, SS 2017) Gerhard Woeginger

Graphentheorie Graphentheorie. Grundlagen Bäume Eigenschaften von Graphen Graphen-Algorithmen Matchings und Netzwerke

Definition Ein gerichteter Graph G = (V, E) ist ein Graph von geordneten Paaren (u, v) mit u V und v V.

2. Repräsentationen von Graphen in Computern

Rückblick: Starke Zusammenhangskomponenten

15. Elementare Graphalgorithmen

Graphen. Leonhard Euler ( )

Vollständiger Graph. Definition 1.5. Sei G =(V,E) ein Graph. Gilt {v, w} E für alle v, w V,v w, dann heißt G vollständig (complete).

Vorlesung Informatik 2 Algorithmen und Datenstrukturen

Kapitel 12: Induktive

Beispiel Strassennetz

Relationen und Graphentheorie

Graphalgorithmen 1. Tillmann Zipperer Tillmann Zipperer Graphalgorithmen / 40

Grundbegriffe der Informatik

1. Motivation / Grundlagen 2. Sortierverfahren 3. Elementare Datenstrukturen / Anwendungen 4. Bäume / Graphen 5. Hashing 6. Algorithmische Geometrie

3. Die Datenstruktur Graph

1. Klausur zur Vorlesung Algorithmentechnik Wintersemester 2008/2009

Graphen und Bäume. A.1 Graphen

9 Minimum Spanning Trees

Diskrete Strukturen Kapitel 4: Graphentheorie (Grundlagen)

Am Dienstag, den 15. Dezember, ist Eulenfest. 1/60

Graphalgorithmen I. Katharina Reif Hallo Welt -Seminar - LS 2

Vorlesung Datenstrukturen

Freie Bäume und Wälder

Programmierung 2 Studiengang MI / WI

Algorithmische Graphentheorie

Algorithmen und Datenstrukturen

Algorithmische Graphentheorie

Massive Parallelität : Neuronale Netze

Einführung in die Informatik I

Algorithmen und Datenstrukturen

Algorithmen & Datenstrukturen 2 Praktikum 3

Graphen. Graphen und ihre Darstellungen

Kürzeste Wege in Graphen. Orte mit Straßenverbindungen. Coma I Rolf Möhring

5. Bäume und Minimalgerüste

Graphen. Definitionen

12. Graphen. Notation, Repräsentation, Traversieren (DFS, BFS), Topologisches Sortieren, Ottman/Widmayer, Kap ,Cormen et al, Kap.

Datenstrukturen und Algorithmen

1 Datenstrukturen Datenstrukturen und Algorithmen

Transkript:

5. Compiler Gliederung 1. Struktur eines Compilers 2. Syntaxanalyse durch rekursiven Abstieg 3. Ausnahmebehandlung 4. Arrays und Strings 6. Sortieren und Suchen 1. Grundlegende Datenstrukturen 2. Bäume 3. Hash-Verfahren (Streuspeicherung) 7. Graphen 1. Darstellung und Topologisches Sortieren 2. Kürzeste Wege 3. Fluß- und Zuordnungsprobleme

Graphen Ein (gerichteter) Graph ist ein Paar G = <V, E>, wobei gilt: V ist eine endliche Menge von Knoten (engl. : Vertex) und E ist eine zweistellige Relation auf V, d.h. E V x V. Die Elemente von E werden Kanten (engl. : Edge) genannt. Gilt G = <V, E > mit V V und E E, so heißt G Teilgraph von G.

Graphen: Beispiele (1) V1 = Menge aller Flughäfen in Deutschland. G1 = { (x,y) V1 x V1 Es gibt einen Direktflug zwischen x und y } (2) V2 = Bevölkerung von Erlangen G2 = { (x,y) V2 x V2 x kennt y } (3) V3 = Bevölkerung von Erlangen G3 = { (x,y) V3 x V3 x ist verheiratet mit y }. G3 ist Teilgraph von G2

Sei G= <V, E>: Bildliche Darstellung von Graphen Einen Knoten v V stellt man durch einen Punkt oder durch einen kleinen Kreis dar. Eine Kante (x,y) E stellt man durch einen Pfeil vom Knoten x zum Knoten y dar. Beispiel: V = {A,B,C,D,E,F,G,H } E = {(A,D), (D,A), (A,B), (B,C), (C,A), (B,E), (A,E), (F,G), (F,F)}. A C B D E H F G

Ungerichtete Graphen Sei G = <V,E>. Falls für jedes e E mit e = (v1,v2) gilt: e = (v2,v1) E, so heißt G ungerichteter Graph, ansonsten gerichteter Graph. Die Relation E ist in diesem Fall symmetrisch. Bei einem ungerichteten Graphen gehört zu jedem Pfeil von x nach y auch ein Pfeil von y nach x. Daher lässt man Pfeile ganz weg und zeichnet nur ungerichtete Kanten.

V = einige Städte Ungerichtete Graphen: Beispiel E = { (x,y) Es gibt eine direkte Bahnverbindung zwischen x und y } Marburg 4 Kassel Köln 5 Bonn 0 Gießen 3 7 2 Fulda 1 Frankfurt 6 Mannheim 8 Würzburg

Pfade, Zyklen und Gewichte Eine Kante k = (x,y) heißt inzident zu x und y. Ein Pfad (oder Weg) von x nach y ist eine Folge (x=a 0, a 1,..., a p =y) von Knoten mit (a i, a i+1 ) E. p wird die Länge des Weges von x nach y genannt. In einem einfachen Pfad kommt jeder Knoten höchstens einmal vor. Ein Pfad der Länge p > 1 von x nach x, in dem außer x kein Knoten mehr als einmal vorkommt, heißt Zyklus. Ein gerichteter Graph <V, E> heißt zyklenfrei oder gerichteter azyklischer Graph (engl: directed acyclic graph, kurz: dag), wenn er keine Zyklen enthält.

Beispiele (B, C, A, D, A) ist ein Pfad von B nach A. Er enthält einen Zyklus: (A, D, A). (C, A, B, E) ist einfacher Pfad von C nach E. A B D F (F, F, F, G) ist ein Pfad. H (A, B, C, A) und (A, D, A) und (F, F) sind die einzigen Zyklen. (A, B, E, A) ist kein Pfad und kein Zyklus. C E G <{A,B,C,E}, {(A,B), (B,C), (B,E), (A,E)}> ist ein azyklischer Teilgraph von G.

Bewertete Graphen Ein Graph G = <V, E> kann zu einem bewerteten Graphen G = <V, E, gw(e)> erweitert werden, wenn man eine Gewichtsfunktion gw: E int (oder gw: E float/double) hinzunimmt, die jeder Kante e E ein (positives, ganzzahliges oder reelles) Gewicht gw(e) zuordnet. Für einen Weg w = (x=a 0, a 1,..., a p =y) heißt p-1 L(w) = Σ gw(a i, a i+1 ) i=0 die bewertete Länge von w. Im folgenden Beispiel gilt: L (Marburg, Gießen, Frankfurt, Mannheim) = 184

Bewertete Graphen : Beispiel 1 Köln 5 34 Bonn 0 174 224 Marburg 7 30 Gießen 3 66 181 1 104 106 104 Frankfurt 4 Kassel 96 2 Fulda 93 6 88 136 8 Würzburg Mannheim

Bewertete Graphen: ein weiteres Beispiel San Rafael 1 18 15 Richmond 2 15 Rund um die Bucht von San Francisco San Francisco 0 15 Pacifica 14 15 Half Moon Bay 13 12 3 20 San Mateo 4 18 25 Palo Alto Oakland 20 5 Hayward 20 14 7 Fremont 15 20 6 15 10 9 8 San Jose Santa Clara 50 35 10 Scotts Valley 10 70 12 Santa Cruz 60 Watsonville 11

Zusammenhangskomponenten: Beispiel Ungerichtete Graphen und Zusammenhang Ungerichtete Graphen sind Spezialfälle von gerichteten Graphen. Zusätzlich soll für ungerichtete Graphen gelten: G heißt zusammenhängend, wenn es zwischen je zwei (verschiedenen) Knoten einen Weg gibt. Ist G nicht zusammenhängend, so zerfällt er in eine Vereinigung zusammenhängender Komponenten (auch Zusammenhangskomponenten genannt). Ein zusammenhängender zyklenfreier Graph ist ein Baum. Eine Gruppe paarweise nicht zusammenhängender Bäume heißt Wald. Jeder zyklenfreie ungerichtete Graph ist also ein Wald. A C B D E H F G

Starke Zusammenhangskomponenten: Beispiel Zusammenhang in gerichteten Graphen Die Definitionen für Zusammenhang und Zusammenhangskomponenten lassen sich für gerichteten Graphen ausdehnen: Ein gerichteter Graph G heißt stark zusammenhängend, wenn es zwischen je zwei (verschiedenen) Knoten einen Weg gibt. Für einen beliebigen Graphen G kann man die Menge seiner starken Zusammenhangskomponenten betrachten. Zwei Knoten a und b liegen in der gleichen Komponente Z, wenn sowohl ein Weg von a nach b als auch einer von b nach a in Z existiert. Ein gerichteter Graph G heißt schwach zusammenhängend, wenn der entsprechende ungerichtete Graph, der aus G durch Hinzunahme aller Rückwärtskanten entsteht, zusammenhängend ist. A C B D E H F G

Aufspannender Baum Ist G zusammenhängend und R ein zusammenhängender, zyklenfreier Teilgraph von G, der alle Knoten von G enthält, so heißt R ein (auf)spannender oder erzeugender Baum (engl.: spanning tree) von G. Einfacher Algorithmus SpT zur Konstruktion des (auf)spannenden Baums für G: Solange es einen Zyklus gibt, entferne eine Kante aus diesem Zyklus Rekursiver Algorithmus SpT zur Konstruktion des (auf)spannenden Baums für G: Markiere einen beliebigen Knoten v V Wiederhole für alle von v ausgehenden Kanten e = (v,v') E: Wenn v' unmarkiert, markiere v' und führe SpT (v') aus, sonst lösche e (und gehe zur nächsten Kante weiter).

Erzeugender Baum : Beispiel Ein Graph G Ein erzeugender Baum von G

Repräsentation von Graphen Für die Repräsentation eines Graphen kommen in erster Linie zwei Datenstrukturen in Frage: eine Boolesche Matrix (auch Adjazenzmatrix genannt): eine Liste oder ein Array von Listen (für die Knoten des Graphen und deren jeweilige Verbindungen). Repräsentation durch eine Adjazenzmatrix: Ein Graph G = ( V, E) ist i.w. durch die Angabe seiner Kanten E V x V bestimmt. So wie Teilmengen von V durch Boolesche Arrays dargestellt werden können, kann man Teilmengen von V V durch Boolesche Matrizen (sog. Adjazenzmatrizen) darstellen. boolean [][] Graph; Dies setzt natürlich voraus, daß wir mit V eine Aufzählung der Knoten des Graphen haben.

Adjazenzmatrix: Beispiel String [] Knoten = {"A", "B", "C", "D", "E", "F", "G", "H"}; boolean [][] Kanten = { {false, true, false, true, true, false, false, false}, {false, false, true, false, true, false, false, false},... // usw. }; A C B D E H F G A B C D E F G H A x x B x C D E F G x x x x x x H ( True = x, False = " " )

Definition einer Graph-Klasse (1) class Graph{ String [] Knoten; int KnotenZahl; int[][] Kanten ; Graph(String [] Knotenliste, int [] [] Kantenliste){ Knoten = Knotenliste; Kanten = Kantenliste; KnotenZahl = knoten.length; } }

Bewertete Adjazenzmatrizen (1) Viele der klassischen Anwendungsbeispiele für Graphen kommen aus dem Bereich der Verkehrsnetze. Wir wollen daher die folgenden Algorithmen anhand zweier umfangreichen Beispiele aus diesem Bereich erläutern. Kanten sind mögliche direkte Verkehrsverbindungen (Straßen) zwischen Städten. Bewertet werden sie mit einer Maßzahl, welche die Entfernung und/oder den durchschnittlichen Zeitaufwand für eine Fahrt zwischen den Städten reflektiert. Dabei haben die Knoten jeweils einen Namen (den Städtenamen) und eine Nummer in der Aufzählung. Daraus kann man dann eine Matrixdarstellung gewinnen.

Bewertete Adjazenzmatrizen (2) Bei dieser Matrix sind die Einträge keine Booleschen Werte mehr, sondern entsprechen den Bewertungen der Kanten. Wenn der Wert nicht in der Matrix erscheint, bedeutet das, daß keine direkte Verbindung zwischen den entsprechenden Städten existiert. In der Diagonalen steht die Bewertung der Verbindung jeder Stadt mit sich selbst. Diese wird hier stets mit 0 angenommen. Wir haben damit das Prinzip der Adjazenzmatrix auf bewertete Graphen erweitert. Statt eines booleschen Werts speichert man das Gewicht gw (u,v) jeder Kante an an der betreffenden Position M[u,v] der Matrix M. M. Ist G ein ungerichteter Graph, so ist die Matrix symmetrisch - d.h. man kommt im Prinzip mit einer Dreiecksmatrix aus.

Bewertete Adjazenzmatrix: Beispiel 1 0 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 7 8 BN F FD GI KS K MA MR WÜ BN 0 181 - - - 34 224 - - F 181 0 104 66 - - 88-136 FD - 104 0 106 96 - - - 93 GI - 66 106 0-174 - 30 - KS - - 96-0 - - 104 - K 34 - - 174-0 - - - MA 224 88 - - - - 0 - - MR - - - 30 104 - - 0 - WÜ - 136 93 - - - - - 0

Bewertete Adjazenzmatrix: Beispiel 2 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 0 0 18-12 20 - - - - - - - - - 15 1 18 0 15 - - - - - - - - - - - - 2-15 0 15 - - - - - - - - - - - 3 12-15 0-20 - - - - - - - - - 4 20 - - - 0 20 18 - - - - - - 25-5 - - - 20 20 0-14 - - - - - - - 6 - - - - 18-0 15-10 - - - - - 7 - - - - - 14 15 0 20 - - - - - - 8 - - - - - - - 20 0 15-60 - - - 9 - - - - - - 10-15 0 35 - - - - 10 - - - - - - - - - 35 0-10 - - 11 - - - - - - - - 60 - - 0 70 - - 12 - - - - - - - - - - 10 70 0 50-13 - - - - 25 - - - - - - - 50 0 15 14 15 - - - - - - - - - - - - 15 0

Adjazenzmatrix für Beispiel 1 Bildung einer Instanz der Klasse Graph, um den Beispiel-1- Graphen zu repräsentieren. Graph Bsp1 = new Graph( {"Bonn", "Frankfurt", "Fulda", "Gießen", "Kassel", "Köln", "Mannheim", "Marburg", "Würzburg" }, { }); { 0, 181, 0, 0, 0, 34, 224, 0, 0}, {181, 0, 104, 66, 0, 0, 88, 0, 136}, { 0, 104, 0, 106, 96, 0, 0, 0, 93}, { 0, 66, 106, 0, 0, 174, 0, 30, 0}, { 0, 0, 96, 0, 0, 0, 0, 104, 0}, { 34, 0, 0, 174, 0, 0, 0, 0, 0}, {224, 88, 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 30, 104, 0, 0, 0, 0}, { 0, 136, 93, 0, 0, 0, 0, 0, 0}

Adjazenzmatrix für Beispiel 2 Graph Bsp2 = new Graph( { "San Francisco", "San Rafael", "Richmond", "Oakland", "San Mateo", "Hayward", "Palo Alto", "Fremont", "San Jose", "Santa Clara", "Scotts Valley", "Watsonville", "Santa Cruz", "Half Moon Bay", "Pacifica" }, { { 0, 18, 0, 12, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15}, {18, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, { 0, 15, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {12, 0, 15, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {20, 0, 0, 0, 0, 20, 18, 0, 0, 0, 0, 0, 0, 25, 0}, { 0, 0, 0, 20, 20, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 18, 0, 0, 15, 0, 10, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 14, 15, 0, 20, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0, 20, 0, 15, 0, 60, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 10, 0, 15, 0, 35, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 10, 0, 0}, { 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 70, 0, 0}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 70, 0, 50, 0}, { 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 50, 0, 15}, {15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0} });

Knoten- und Kantenzugriffe Der Zugriff auf einzelne Knoten und Kanten ist mit Hilfe einfacher Zugriffsfunktionen möglich: String gibknoten (int k) { return Knoten[k];} int gibkantenw (int u, int v) { return Kanten[u][v];} Beispiel: Graph Bsp1 = new Graph(); Bsp1.gibKnoten (3); // Ergebnis: "Gießen" Bsp1.gibKantenW (3, 7); // Ergebnis: 30

Adjazenzlisten (1) A D Eine alternative, weniger speicheraufwendige Methode, einen Graphen darzustellen, besteht darin, zu jedem Knoten eine Liste zu definieren, in der die unmittelbaren Nachbarn samt der Gewichte ihrer Verbindungen enthalten sind. C A B B E C D F H G E F G H Dabei wird jedem Knoten eine Adjazenzliste (= Liste seiner Nachbarknoten) zugeordnet. B D C E A A F G E

Adjazenzlisten (2) Die Darstellung eines Graphen mit einer Adjazenzliste spart Speicherplatz, da die speicheraufwendige (und hochgradig redundante) Adjazenzmatrix vermieden wird. Leider ist bei der Listendarstellung der Aufwand für einen direkten Zugriff auf den Wert einer Kante von x nach y hoch. Dieser Zugriff erfolgt jedoch bei typischen Graphalgorithmen recht häufig. Im Falle der Verwendung einer Adjazenzmatrix ist der Zugriff direkt möglich, im Falle der Listendarstellung führt der entsprechende Zugriff zu einer Suche in der Liste aller Nachbarn.

Adjazenzlisten für Beispiel 1 0 Bonn 1 181 5 34 6 224 null 1 Frankfurt 0 181 2 104 3 66 6 88 8 136 null 2 Fulda 1 104 3 106 4 96 8 93 null 3 Gießen 1 66 2 106 5 174 4 Kassel 2 96 7 104 null 5 Köln 0 34 3 174 null 6 Mannheim 0 224 1 88 null 7 Marburg 3 30 4 104 null 8 Würzburg 1 136 2 93 null 7 30 null

Adjazenzlisten für Beispiel 2 0 San Francisco 18 2 12 4 20 5 15 15 1 San Rafael 18 1 15 3 null 2 Richmond 15 2 15 4 null null 3 Oakland 12 1 15 3 20 6 null 4 San Mateo 20 1 20 6 18 7 25 4 5 Hayward 20 4 20 5 14 8 null 6 Palo Alto 18 5 15 8 10 10 null 7 Fremont 14 6 15 7 20 9 null 8 San Jose 20 8 15 10 60 12 null 9 Santa Clara 10 7 15 9 35 11 null 10 Scotts Valley 35 10 10 13 null 11 Watsonville 60 9 70 13 null 12 Santa Cruz 10 10 70 12 50 14 null 13 Half Moon Bay 50 13 25 5 15 15 null 14 Pacifica 15 14 15 1 null

Adjazenzliste für Beispiel 2 (1) Eine Klasse zur Repräsentation von Verbindungen class Verbindung{ int Laenge; int ziel; Verbindung next; } Verbindung(int l, int w, Verbindung v){ Laenge = l; ziel = w; next = v; }

Adjazenzliste für Beispiel 2 (2) Eine Klasse zur Repräsentation von Knoten class KnotenTyp{ String Name; Verbindung Nachbarn; } KnotenTyp(String s, Verbindung v){ Name = s; Nachbarn = v; }

Definition einer Graph-Klasse (2) class Graph{ KnotenTyp [] Knoten; int KnotenZahl; } Graph(Knotentyp [] KnotenTypListe){ Knoten = KnotenTypListe; KnotenZahl = knoten.length; }

Adjazenzliste für Beispiel 2 (3) Realisierung des Graphen KnotenTyp [] Knoten = new KnotenTyp[15]; Knoten[ 0] = new KnotenTyp("San Francisco", new Verbindung(18, 1, new Verbindung(12, 3, new Verbindung(20, 4, new Verbindung(15, 14, null))))); Knoten[ 1] = new KnotenTyp("San Rafael", new Verbindung(18, 0, new Verbindung(15, 2, null))); Knoten[ 2] = new KnotenTyp("Richmond", new Verbindung(15, 1, new Verbindung(15, 3, null)));... /// usw. usw. usw... Graph mygraph= new Graph(Knoten);

Knoten- und Kantenzugriffe Der Zugriff auf einzelne Knoten ist immer noch einfach: String gibknoten (int k) { return Knoten[k].Name[k]; } Der Zugriff auf einzelne Kanten ist nur mit Hilfe einer aufwendigeren Zugriffsfunktionen möglich: int gibkantenw (int u, int v) { Verbindung vp = Knoten[u].Nachbarn; while (vp!= null){ if (vp.ziel == v) return vp.laenge; vp = vp.next; } return 0; }

Implementierung durch Listen von Listen (1) Eine weitere Möglichkeit zur Implementierung von Graphen besteht darin, auch die Folge der Knoten auf eine Liste abzubilden, d.h. der gesamte Graph wird durch eine Liste von Listen dargestellt. A B D E B C E A D C A F D A C B E H G E F G F G H

Implementierung durch Listen von Listen (2) class Edge { int dest, cost; public Edge (int d, int c) { dest = d; cost = c; } } public class Graph { private Hashtable labels; private Vector nodes; public Graph () { labels = new Hashtable (); nodes = new Vector (); }

Implementierung durch Listen von Listen (3) public void addnode (String label) { if (labels.contains (label)) throw new NodeAlreadyDefinedException (); nodes.addelement (new LinkedList ()); int idx = nodes.size () - 1; labels.put (label, new Integer (idx)); } public int getnodeid (String label) { Integer i = (Integer) labels.get (label); if (i == null) throw new NoSuchElementException (); return i.intvalue (); } public void addedge (String src, String dest, int cost) { LinkedList adjlist = (LinkedList) nodes.elementat (getnodeid (src)); adjlist.add (new Edge (getnodeid (dest), cost)); } public Iterator getedges (int node) { return ((LinkedList) nodes.elementat (node)).iterator (); }

Vergleich der Implementierungen Alle hier betrachteten Möglichkeiten zur Implementierung von Graphen haben ihre spezifischen Vor- und Nachteile. Seien n = Knotenzahl und m = Kantenzahl eines Graphen G. Vorteile Nachteile Adjazenzmatrix Adjazenzliste Liste von Listen Berechnung der Inzidenz mit O(1) Platzbedarf beträgt nur O(n+m) Knoten lassen sich flexibel hinzufügen/ löschen hoher Platzbedarf und teure Initialisierung: beide O(n 2 ) Effizienz der Kantensuche abhängig von Knotenordnung O(m) Effizienz von Knoten- und Kantensuche abhängig von Listenposition O(m.n)

Literatur Die Vorlesungsfolien wurden aus der Vorlesung Informatik II a, SS 2002 von Prof. Sommer (Uni-Marburg) übernommen