Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Informatik 2 Datenstrukturen Prof. Dr.-Ing. Holger Vogelsang

Ähnliche Präsentationen


Präsentation zum Thema: "Informatik 2 Datenstrukturen Prof. Dr.-Ing. Holger Vogelsang"—  Präsentation transkript:

1 Informatik 2 Datenstrukturen Prof. Dr.-Ing. Holger Vogelsang

2 Holger Vogelsang Inhaltsverzeichnis n Abstrakte Datentypen (3) Abstrakte Datentypen (3) n Datenstrukturen in Java (11) Datenstrukturen in Java (11) n Elementare Datenstrukturen (14) Elementare Datenstrukturen (14) n Iteratoren (32) Iteratoren (32) n Hashtabellen (48) Hashtabellen (48) n Bäume (92) Bäume (92) n Graphen (180) Graphen (180) Informatik 2 - Datenstrukturen2

3 Holger Vogelsang Abstrakte Datentypen Übersicht Informatik 2 - Datenstrukturen3 Typinfo., I/O Annota- tionen Laufzeit- typinfo. Ein-, Ausgabe Entwurf Prinzipien Verbindung von Modulen OSGiSpring Grafische Oberflä- chen ÜbersichtLayoutsWidgets Grafik- operationen Grafik- widgets Effekte, Animationen Offene Punkte Ereignisse Daten- strukturen ADTs Elementare Datenstrukturen Hash- tabellen BäumeGraphenIteratoren Datenstrukturen in Java

4 Holger Vogelsang Informatik 2 - Datenstrukturen4 Abstrakte Datentypen Übersicht n Bisher: u Einführung in objektorientierte Programmierung u Einfache Datenstrukturen wie Array, Vektor und Liste n Jetzt: u Festlegung von Schnittstelle und Funktionalität einer Datenstruktur, ohne eine konkrete Implementierung zu verwenden Definition: Abstrakter Datentyp Ein abstrakter Datentyp (ADT) ist ein Datentyp (eine Menge von Werten und eine Sammlung von Operationen auf diesen Werten), der nur über eine Schnittstelle zugänglich ist. Ein ADT kann bei identischer Funktionalität unterschiedliche mögliche Implementierungen besitzen.

5 Holger Vogelsang Informatik 2 - Datenstrukturen5 Abstrakte Datentypen Übersicht n Eine ADT-Spezifikation besteht aus einer Signatur und Axiomen (hier stark vereinfacht dargestellt, die mathematischen Begriffe wurden teilweise nicht verwendet). u Signatur = (S, ) mit -S = Die Menge von Datentypen, die der ADT verwendet. Einer der Datentypen wird in der Regel durch den ADT neu definiert. Die anderen existieren bereits. - = Die Menge von Methoden und Konstanten des ADT. u Axiome legen die Semantik und damit das Verhalten des ADT unabhängig von einer konkreten Implementierung fest. n In diesen Unterlagen werden teilweise Beispiele aus dem Buch Algorithmen und Datenstrukturen von Saake und Sattler übernommen. Die Darstellung der ADTs entspricht auch der Syntax aus dem Buch.

6 Holger Vogelsang Informatik 2 - Datenstrukturen6 Abstrakte Datentypen Beispiel: Liste Unvollständiger ADT für eine Liste List von Elementen des Datentyps T. type List(T) import Nat operators [] List _:_ : T List List addFirst : List T List getFirst : List T getTail : List List size : List Nat axioms l : List, x : T getTail(addFirst(l, x)) = l getFirst(addFirst(l, x)) = x getFirst(x : l) = x getTail(x : l) = l size([]) = 0 size(x : l) = succ(size(l)) x : l Element x und weitere Listenelemente in l [] erzeugt eine neue, leere Liste succ entstammt ADT für natürliche Zahlen _:_ Konstruktions- vorschrift (neuer Operator)

7 Holger Vogelsang Informatik 2 - Datenstrukturen7 Abstrakte Datentypen Beispiel: Liste n Mögliche Listen: [] leere Liste 1 : [] Liste mit dem Element 1 1 : 2 : 3 : 4 : [] Liste mit den Elementen 1 bis 4 n Deutlich erkennbar: Das Wissen über die konkrete Implementierung der Liste ist für die Anwendung nicht erforderlich. u In einer Programmiersprache: Schnittstelle der Klasse (öffentliche Methoden und Datentypen) sowie die Dokumentation des Verhalten sind erforderlich. u Die Art der Implementierung ist unwichtig (sofern sie das Laufzeitverhalten nicht beeinflusst). n Wozu dient das Wissen über ADTs? ADT könnte in Java eine Schnittstelle (ein interface ) sein. u Die konkrete Implementierung implementiert die Schnittstelle. u Es lässt sich prima auf der Schnittstelle arbeiten.

8 Holger Vogelsang Informatik 2 - Datenstrukturen8 Abstrakte Datentypen Anwendung eines ADT Beispiel ADT List und konkrete Java-Umsetzung der Operatoren type List(T) import Nat operators [] List _:_ : T List List addFirst : List T List getFirst : List T getTail : List List size : List Nat axioms l : List, x : T getTail(addFirst(l, x)) = l getFirst(addFirst(l, x)) = x getFirst(x : l) = x getTail(x : l) = l size([]) = 0 size(x : l) = succ(size(l)) > List +add(int i, e: T): boolean +get(index: int): T +remove(index: int): T +size(): int LinkedList +add(int i, e: T): boolean +get(index: int): T +remove(index: int): T +size(): int ArrayList +add(int i, e: T): boolean +get(index: int): T +remove(index: int): T +size(): int Verkettete Liste Vektor T: class

9 Holger Vogelsang Informatik 2 - Datenstrukturen9 Abstrakte Datentypen Anwendung eines ADT Beispiel ADT List und konkrete Java-Umsetzung der Axiome type List(T) import Nat operators [] List _:_ : T List List addFirst : List T List getFirst : List T getTail : List List size : List Nat axioms l : List, x : T getTail(addFirst(l, x)) = l getFirst(addFirst(l, x)) = x getFirst(x : l) = x getTail(x : l) = l size([]) = 0 size(x : l) = succ(size(l)) z.B. als Dokumentation oder zur Validierung einer Implementierung

10 Holger Vogelsang Informatik 2 - Datenstrukturen10 Abstrakte Datentypen ADT: Beschreibung der Axiome n Die Axiome können durch nahezu beliebige Sprachen beschrieben werden. n Komplexere Aussagen sind z.B. mit OCaml (funktionale Programmiersprache, siehe möglich soll hier nicht näher vertieft werden.

11 Holger Vogelsang Typinfo., I/O Annota- tionen Laufzeit- typinfo. Ein-, Ausgabe Entwurf Prinzipien Verbindung von Modulen OSGiSpring Datenstrukturen in Java Übersicht Informatik 2 - Datenstrukturen11 Grafische Oberflä- chen ÜbersichtLayoutsWidgets Grafik- operationen Grafik- widgets Effekte, Animationen Offene Punkte Ereignisse Daten- strukturen ADTs Elementare Datenstrukturen Hash- tabellen BäumeGraphenIteratoren Datenstrukturen in Java

12 Holger Vogelsang Informatik 2 - Datenstrukturen12 Datenstrukturen in Java Übersicht n Vereinfachte Übersicht über die Collections-Klassen in Java

13 Holger Vogelsang Datenstrukturen in Java Schnittstellen Iterable : Über die Datenstruktur kann direkt iteriert werden siehe Iteratoren. Collection : Gruppe von Elementen, Duplikate können erlaubt sein List : Collection mit einer Ordnung, Indexzugriff ist erlaubt (möglicherweise ineffizient) RandomAccess : Leere Schnittstelle, der Indexzugriff ist mit konstanter Zeit möglich. Queue : spezielle Queue-Operationen vorhanden Deque : Queue mit Einfüge- und Löschoperationen an Anfang und Ende Set : Menge von Elementen ohne Duplikate SortedSet : Menge mit einer Totalordnung der Elemente (anhand ihrer natürlichen Ordnung oder anhand eines Vergleichs-Objektes) NavigableSet : SortedSet mit Methoden, um kleinere oder größere Elemente zu finden Map : Bildet Schlüssel-Objekte (K) auf Werte (V) ab. SortedMap : Eine Map mit einer Totalordnung der Elemente NavigableMap : SortedMap mit Methoden, um kleinere oder größere Schlüssel zu finden. Informatik 2 - Datenstrukturen13

14 Holger Vogelsang Typinfo., I/O Annota- tionen Laufzeit- typinfo. Ein-, Ausgabe Entwurf Prinzipien Verbindung von Modulen OSGiSpring Elementare Datenstrukturen Übersicht Informatik 2 - Datenstrukturen14 Grafische Oberflä- chen ÜbersichtLayoutsWidgets Grafik- operationen Grafik- widgets Effekte, Animationen Offene Punkte Ereignisse Daten- strukturen ADTs Elementare Datenstrukturen Hash- tabellen BäumeGraphenIteratoren Datenstrukturen in Java

15 Holger Vogelsang Informatik 2 - Datenstrukturen15 Elementare Datenstrukturen Übersicht in Java n Elementare Datenstrukturen

16 Holger Vogelsang Informatik 2 - Datenstrukturen16 Elementare Datenstrukturen Vektor – Prinzip Die Klassen ArrayList und Vector verwalten dynamisch beliebig viele Objekte. n Die Anordnung der Objekte erfolgt sequentiell. n Die interne Implementierung erfolgt durch ein Array. n Der Vektor besitzt eine Referenz auf den Speicherbereich. n Ein Vektor eignet sich besonders für einen schnellen freien Zugriff über Indizes auf die Elemente. n Der Indexzugriff erfolgt immer geprüft. Vector ist im Gegensatz zu ArrayList thread-sicher und damit langsamer. Extra Platz ArrayList -values[*]: E -size: int E: class ArrayList size

17 Holger Vogelsang Informatik 2 - Datenstrukturen17 Elementare Datenstrukturen Beispiel zu ArrayList n Beispiel: import java.util.ArrayList; public class ArrayListTest { public static void main(String[] args) { ArrayList contents = new ArrayList<>(10); for (int i = 0; i < 10; i++) { contents.add(i * i); } int v = contents.get(12); // Geprüfter Zugriff --> // Abfangen der Fehler System.out.println(contents.size()); System.out.println(contents.contains(2)); }

18 Holger Vogelsang Informatik 2 - Datenstrukturen18 Elementare Datenstrukturen ArrayList und Vektor in Java Beide implementieren RandomAccess : Indexzugriff in konstanter Zeit

19 Holger Vogelsang Informatik 2 - Datenstrukturen19 Elementare Datenstrukturen Vektor – Aufwandsabschätzungen Aufwandsabschätzungen für die Vektor-Klassen OperationAufwand EinfügenO(N) LöschenO(N) IndexzugriffO(1) Suche, sortierte DatenO(ln N) Binärsuche Suche, unsortierte DatenO(N) sequentielles Durchlaufen

20 Holger Vogelsang Informatik 2 - Datenstrukturen20 Elementare Datenstrukturen Liste: Prinzip n Prinzip einer einfach verketteten Liste: n Die Liste besitzt einen Kopf und ein Ende. n Jeder Listeneintrag verweist auf seinen Nachfolger. n Jeder Listeneintrag beinhaltet die Nutzdaten. LinkedList E: class Listelement value Listelement value Listelement value Listelement E: class -value: E last first last 0, 1 next

21 Holger Vogelsang Informatik 2 - Datenstrukturen21 Elementare Datenstrukturen Liste: Prinzip n Prinzip einer doppelt verketteten Liste: n Die Liste besitzt einen Kopf und ein Ende. n Jeder Listeneintrag verweist auf seinen Nachfolger und Vorgänger n Jeder Listeneintrag beinhaltet die Nutzdaten. LinkedList Listelement value Listelement value Listelement value last first LinkedList E: class Listelement E: class -value: E first last 0, 1 next 0, 1 prev

22 Holger Vogelsang Informatik 2 - Datenstrukturen22 Elementare Datenstrukturen Liste in Java LinkedList implementiert nicht RandomAccess : Indexzugriff nicht in konstanter Zeit!

23 Holger Vogelsang Informatik 2 - Datenstrukturen23 Elementare Datenstrukturen Liste – Aufwandsabschätzung OperationAufwand Einfügen (an Index x)O(N) sequentielles Durchlaufen Einfügen (Anfang, Ende)O(1) Löschen (an Index x)O(N) sequentielles Durchlaufen Löschen (Anfang, Ende)O(1) IndexzugriffO(N) sequentielles Durchlaufen Suche, sortierte DatenO(N) sequentielles Durchlaufen Suche, unsortierte DatenO(N) sequentielles Durchlaufen

24 Holger Vogelsang Informatik 2 - Datenstrukturen24 Elementare Datenstrukturen Queue – Prinzip n Prinzip einer Queue (Warteschlange): Daten werden in einer Queue am Ende mit offer eingetragen und am Anfang der Queue mit poll entfernt Warteschlange (häufig auch push / pop ). Es gibt einige Container-Klassen, die Queue-Funktionalität einsetzen. Beispiel: LinkedList. n Einsatzgebiete einfaches Nachrichtensystem (Nachricht ablegen = offer, Nachricht abholen = poll ). u allgemeine asynchrone Kommunikation zwischen Auftragnehmer und Auftraggeber Queue 0123

25 Holger Vogelsang Informatik 2 - Datenstrukturen25 Elementare Datenstrukturen Queue in Java LinkedList implementiert Queue

26 Holger Vogelsang Elementare Datenstrukturen Queue in Java Die Methoden gibt es doppelt (aus Queue und Deque ): Informatik 2 - Datenstrukturen26 FunktionMethoden mit AusnahmenMethoden ohne Ausnahmen (Fehlercode) Einfügen (push) add(E), push(E)offer(E), addLast(E) Entfernen (pop) remove(), removeFirst()poll(), pollFirst() Auslesen (top) element(), getFirst()peek(), peekFirst()

27 Holger Vogelsang Informatik 2 - Datenstrukturen27 Elementare Datenstrukturen Queue – Prinzip n Arbeitsweise einer Queue an einem Beispiel. n Initialzustand: offer(E4) : poll() : Queue offer poll E1 E2 E3 E1 E2 E3 E4 012 E2 E3 E4

28 Holger Vogelsang Informatik 2 - Datenstrukturen28 Elementare Datenstrukturen Stack – Prinzip n Prinzip eines Stacks (Stapel): Daten werden in einem Stack am Ende mit offer eingetragen und ebenfalls am Ende mit poll entfernt Stapel (häufig auch push / pop ). n Einsatzgebiete u.a.: u Zwischenspeicherung von Objekten, wenn eine Rekursion zu einer Iteration aufgelöst wird. u Text-Parser. Stack 0123

29 Holger Vogelsang Informatik 2 - Datenstrukturen29 Elementare Datenstrukturen Stack in Java Es gibt eine Stack-Klasse, die aber nicht optimal ist. Besser: Klasse, die Deque implementiert.

30 Holger Vogelsang Elementare Datenstrukturen Stack in Java Die Methoden gibt es doppelt (aus Queue und Deque ): Informatik 2 - Datenstrukturen30 FunktionMethoden mit AusnahmenMethoden ohne Ausnahmen (Fehlercode) Einfügen (push) add(E), push(E)offer(E), addLast(E) Entfernen (pop) removeLast()pollLast() Auslesen (top) getLast()peekLast()

31 Holger Vogelsang Informatik 2 - Datenstrukturen31 Elementare Datenstrukturen Stack – Prinzip n Arbeitsweise eines Stacks an einem Beispiel. n Initialzustand: offer(E4) : pollLast() : Stack 012 E1 E2 E3 offer 0123 E1 E2 E3 E4 E1 E2 E3 pollLast 012

32 Holger Vogelsang Typinfo., I/O Annota- tionen Laufzeit- typinfo. Ein-, Ausgabe Entwurf Prinzipien Verbindung von Modulen OSGiSpring Iteratoren Übersicht Informatik 2 - Datenstrukturen32 Grafische Oberflä- chen ÜbersichtLayoutsWidgets Grafik- operationen Grafik- widgets Effekte, Animationen Offene Punkte Ereignisse Daten- strukturen ADTs Elementare Datenstrukturen Hash- tabellen BäumeGraphen Iteratoren Datenstrukturen in Java

33 Holger Vogelsang Informatik 2 - Datenstrukturen33 Iteratoren Motivation n Wie lässt sich ein Algorithmus schreiben, der unabhängig von einer konkreten Datenstruktur arbeiten kann? n Wie können beliebig viele Algorithmen quasi parallel eine unbekannte Datenstruktur bearbeiten?

34 Holger Vogelsang Informatik 2 - Datenstrukturen34 Iteratoren Konzept n Problem: Bisher werden Listen oder Vektoren durch eine Schleife, die direkt auf die Elemente des Containers zugreift, durchlaufen. Wie kann aber ein Algorithmus unabhängig von der Klasse (dem Container) geschrieben werden? n Ziel: Konstruktion eines Algorithmus unabhängig von der konkreten Klasse (dem Container). n Lösung: Iteratoren dienen als Bindeglied zwischen den Containern und Algorithmen auf Containern Prinzip Umkehr der Abhängigkeiten! n Iteratoren sind abstrakte Datentypen, mit deren Hilfe auf eine Folge von Objekten zugegriffen werden kann. n Ein Iterator verweist immer auf ein Objekt innerhalb einer Folge von Objekten. n Die Vorlesung behandelt Iteratoren nicht vollständig.

35 Holger Vogelsang Informatik 2 - Datenstrukturen35 Iteratoren Konzept n Mögliche Vektor- und Listenimplementierungen mit Sortierung der Elemente. n Mit einem Iterator können alle Elemente in ihrer Sortierreihenfolge besucht werden. ArrayList Extra Platz LinkedList last first sequentielles Durchlaufen

36 Holger Vogelsang Informatik 2 - Datenstrukturen36 Iteratoren Konzept n Iterator als Bindeglied zwischen Algorithmus und Datenstruktur: ArrayList Algorithmus last first Zugriff auf die Datenstruktur über eine einheitliche Schnittstelle LinkedList erzeugt Zugriff erzeugt Zugriff

37 Holger Vogelsang Informatik 2 - Datenstrukturen37 Iteratoren Funktionsweise n Jede Datenstruktur bietet eigene Iteratoren, die eine der beiden folgenden Schnittstellen implementieren: normaler Iterator, um eine Collection vom Anfang bis zum Ende zu durchlaufen Iterator, um eine List vorwärts und rückwärts zu durchlaufen erlaubt das Ersetzen von Elementen ermöglicht das Auslesen des aktuellen Indexes

38 Holger Vogelsang Informatik 2 - Datenstrukturen38 Iteratoren Funktionsweise n Jede Datenstruktur hat Methoden, die die Iteratorobjekte erzeugen: DatenstruktorErzeugung des Iterators Collection Iterator iterator() List ListIterator listIterator() und Iterator iterator() (weil List auch eine Collection ist )

39 Holger Vogelsang Informatik 2 - Datenstrukturen39 Iteratoren Beispiel import java.util.ArrayList; import java.util.Iterator; import java.util.ListIterator; public class IteratorTest { public static void print( Iterator iter) { while (iter.hasNext()) { System.out.println(iter.next()); } public static void modify( ListIterator iter, E value) { while (iter.hasNext()) { iter.next(); iter.set(value); } public static void main( String[] args) { ArrayList source = new ArrayList<>(); source.add("Hallo 1"); source.add("Hallo 2"); source.add("Hallo 3"); source.add("Hallo 4"); print(source.iterator()); modify(source.listIterator(), "----"); }

40 Holger Vogelsang Informatik 2 - Datenstrukturen40 Iteratoren Weiteres Beispiel import java.util.ArrayList; import java.util.Iterator; import java.util.ListIterator; public class IteratorTest { public static void copy( ListIterator dest, ListIterator source) { while (source.hasNext()) { // Im Ziel überschreiben? if (dest.hasNext()) { dest.next(); dest.set(source.next()); } // Anhängen, da Ziel kürzer else { dest.add(source.next()); } public static void main( String[] args) { ArrayList source = new ArrayList<>(); source.add("Hallo 1"); source.add("Hallo 2"); source.add("Hallo 3"); source.add("Hallo 4"); ArrayList dest = new ArrayList<>(); copy(dest.listIterator(), source.listIterator()); } kopiert von ArrayList in ArrayList

41 Holger Vogelsang Informatik 2 - Datenstrukturen41 Iteratoren Weiteres Beispiel – Variante 2 copy arbeitet auch mit LinkedList, Vector, und anderen Datentypen. public static void main( String[] args) { LinkedList source = new LinkedList<>(); source.add("Hallo 1"); source.add("Hallo 2"); source.add("Hallo 3"); source.add("Hallo 4"); LinkedList dest = new LinkedList<>(); copy(dest.listIterator(), source.listIterator()); } copy kann auch zwischen unterschiedlichen Containern kopieren. public static void main( String[] args) { ArrayList source = new ArrayList<>(); source.add("Hallo 1"); source.add("Hallo 2"); source.add("Hallo 3"); source.add("Hallo 4"); LinkedList dest = new LinkedList<>(); copy(dest.listIterator(), source.listIterator()); } Im SDK wird aber eher mit Collection und List statt mit Iteratoren gearbeitet.

42 Holger Vogelsang Informatik 2 - Datenstrukturen42 Iteratoren Bedeutung von Iteratoren: Beispiel n Die folgenden Klassen verwalten ein einfaches Dateisystem direkt im Hauptspeicher des Computers. File -name: String -access: int -contents: byte[*] Directory -name: String -access: int files 0..*subdirectories 0..* 0, 1parent // Eine Datei im Dateisystem public class File { private String name; // Name private int access; // Rechte private byte[] contents; // Inhalt public File(String name, int access, byte[] contents){} public boolean equals( Object other){} // } // Verzeichnis im Dateisystem public class Directory { private String name; private Directory parent; // Vater private LinkedList subdirectories; private LinkedList files; private int access; // }

43 Holger Vogelsang Informatik 2 - Datenstrukturen43 Iteratoren Bedeutung von Iteratoren: Beispiel n Es ergibt sich ein Baum aus Verzeichnissen, in denen jeweils eine Anzahl von Dateien liegen kann. Ziel: Schreiben einiger Methoden der Directory -Klasse, die über Iteratoren auf den Baum zugreifen. Zählen aller Dateien Methode der Klasse Directory, die die Anzahl der Dateien in dem Verzeichnis sowie seinen Unterverzeichnissen ermittelt. public int countFiles() { int size = files.size(); for (Iterator iter = subdirectories.iterator(); iter.hasNext();) { Directory currentDirectory = iter.next(); size += currentDirectory.countFiles(); } return size; }

44 Holger Vogelsang Informatik 2 - Datenstrukturen44 Iteratoren Bedeutung von Iteratoren: Beispiel Suchen einer Datei Methode der Klasse Directory, die nur in diesem Verzeichnis (nicht in seinen Unterverzeichnissen) eine Datei sucht. Doppelte Dateinamen kommen nicht vor. public boolean containsFile(File file) { for (Iterator iter = files.iterator(); iter.hasNext(); ) { if (iter.next().equals(file)) { return true; } return false; }

45 Holger Vogelsang Informatik 2 - Datenstrukturen45 Iteratoren Bedeutung von Iteratoren n Abstrakte Zugriffe auf Datenstrukturen (nicht auf konkrete Collection-Klassen): u Iteratoren Methoden der Schnittstellen List und Collection -Viele Algorithmen sind auch als statische Methoden in der Klasse Collections vorhanden (sortieren usw.). -Diese arbeiten fast immer auf den Schnittstellen List und Collection.

46 Holger Vogelsang Informatik 2 - Datenstrukturen46 Iteratoren Eine Auswahl an Algorithmen der Klasse Collections Algorithmus (Funktion)Bedeutung static void copy( List dest, List src) Kopiert Elemente eines Containers in einen anderen. Dabei werden die vorhandenen Elemente des Ziels überschrieben. Das Ziel muss genügend Platz für alle Elemente haben. Beispiel: LinkedList src = new LinkedList<>(); LinkedList dest = new LinkedList<>(); src.add("Test"); Collections.copy(dest, src); static void fill( List list, T obj) Überschreibt alle Elemente eines Ziel-Containers mit einem festen Wert. Beispiel: ArrayList a = new ArrayList<>(); a.add("42"); a.add("66"); Collections.fill(a, "9");

47 Holger Vogelsang Informatik 2 - Datenstrukturen47 Iteratoren Eine Auswahl an Algorithmen der Klasse Collections Algorithmus (Funktion)Bedeutung static > void sort(List list) Mit sort kann der Inhalt eines Containers sortiert werden. Diese Methode verwendet den Standardtest equals, um zwei Objekte zu vergleichen. Beispiel: Vector v = new Vector<>(); v.add("66"); v.add("42"); Collections.sort(v); static void sort(List list, Comparator c) Diese Sortier-Methode verwendet den übergebenen Vergleicher, um zwei Objekte zu vergleichen. static void reverse(List list) Dreht die Reihenfolge der Elemente um. Beispiel: Vector v = new Vector<>(); v.add("66"); v.add("42"); Collections.reverse(v);

48 Holger Vogelsang Typinfo., I/O Annota- tionen Laufzeit- typinfo. Ein-, Ausgabe Entwurf Prinzipien Verbindung von Modulen OSGiSpring Hashtabellen Übersicht Informatik 2 - Datenstrukturen48 Grafische Oberflä- chen ÜbersichtLayoutsWidgets Grafik- operationen Grafik- widgets Effekte, Animationen Offene Punkte Ereignisse Daten- strukturen ADTs Elementare Datenstrukturen Hash- tabellen BäumeGraphenIteratoren Datenstrukturen in Java

49 Holger Vogelsang Informatik 2 - Datenstrukturen49 Hashtabellen Motivation n Wie können Daten laufzeiteffizient verwaltet werden? n Welche Bedingungen gelten dabei? n Wie sieht der Speicherbedarf dazu aus? n Idee: Daten werden in einem Array abgelegt und der Index im Array aus den Daten berechnet.

50 Holger Vogelsang Informatik 2 - Datenstrukturen50 Hashtabellen Idee n Problem: Wie kann eine Menge von Werten M, die durch eine Schlüsselmenge K repräsentiert werden kann, effizient verwaltet werden? u schnelles Einfügen u schnelles Suchen u schnelles Löschen n Gesucht ist eine Abbildung H von der Menge der Schlüssel K in den zur Verfügung stehenden Adressraum. n Bisherige Lösung: Listen-, Vektordarstellungen, Arrays,... n Dabei wurde beim Suchen jeweils die Speicheradresse ermittelt. n Jetzt: Neue Lösung, bei der die Werte in einem Vektor oder Array liegen und die Werte mittels einer Schlüsseltransformation auf den Adressraum (den Vektor) abgebildet werden.

51 Holger Vogelsang Informatik 2 - Datenstrukturen51 Hashtabellen Problem der Schlüsselabbildung n Problem: Menge der möglichen Schlüsselwerte ist viel größer als die Menge der freien Speicheradressen. u Beispiel: Die Elemente einer Menge werden mit Schlüsseln der Länge 10 Zeichen beschrieben. Es sollen maximal 1000 Elemente und damit 1000 Adressen verwendet werden. Wie sollen mögliche Schlüssel auf 1000 Adressen verteilt werden? u Schlussfolgerung: Die Abbildungsfunktion H kann nicht eindeutig sein. n Die Funktion H wird Hashfunktion genannt. n Das Array, das die Werte aufnimmt, wird Hashtabelle genannt.

52 Holger Vogelsang Informatik 2 - Datenstrukturen52 Hashtabellen Perfekte Hashfunktion n Eine (perfekte) Hashfunktion kann über einen Schlüsselwert direkt die Position des Objekts im Feld berechnen. n Beispiel: Es existieren 26 Objekte, die Personen beschreiben: public class Person {.... } u Diese Personen werden durch Ihren Nachnamen als Schlüssel identifiziert. Zufällig sind die Namen über das Alphabet verteilt. Es gibt also zu jedem Großbuchstaben genau eine Person, deren Namen mit diesem Schlüssel anfängt. Damit ergibt sich eine perfekte Hashfunktion: Person[] hashtable = new Person[26]; int hash(String key){ return key.charAt(0) – 'A'; } u Dann kann die Person zu einem Schlüssel einfach so gefunden werden: Person dozent = hashtable[ hash("Vogelsang") ];

53 Holger Vogelsang Informatik 2 - Datenstrukturen53 Hashtabellen Perfekte Hashfunktion n Dieser Fall ist ziemlich unwahrscheinlich. n Zumeist werden mehrere Personen den gleichen Anfangsbuchstaben haben und sich dann die Positionen im Feld teilen müssen. n Man spricht dann auch von Kollision. n Bis zu einem gewissen Grad kann man Kollisionen dadurch begegnen, dass man die Hashtabelle größer macht und die Hashfunktion so erweitert, dass zum Beispiel der zweite Buchstabe berücksichtigt wird. Damit das Ergebnis der Berechnung wieder in die Tabelle passt, wird es später modulo der Tabellengröße gerechnet. final int SHIFT = 257; int hash(String key) { return key.charAt(0) + key.charAt(1) * SHIFT; }

54 Holger Vogelsang Informatik 2 - Datenstrukturen54 Hashtabellen Strategien zur Kollisionserkennung n Ab jetzt soll der Fall der nicht-perfekten Hashfunktion betrachtet werden. n Frage: Wie soll verfahren werden, wenn beim Einfügen die Hashfunktion einen Index in der Tabelle ermittelt, der bereits durch einen anderen Wert belegt ist?

55 Holger Vogelsang Informatik 2 - Datenstrukturen55 Hashtabellen Hashtabellen mit Verkettung n Idee: Alle Objekte mit identischen Hashwerten werden am selben Index der Hashtabelle am Ende einer linearen Liste angehängt. HashMap K, V: class list K, V: class listelement K, V: class -data: pair first last 0, 1 next lists *

56 Holger Vogelsang Informatik 2 - Datenstrukturen56 Hashtabellen Hashtabellen mit Verkettung n Vorteil: u Die Hashtabelle kann nicht überlaufen. u Solange überhaupt noch Speicher vorhanden ist, lassen sich auch Elemente in der Tabelle eintragen. n Bezeichnung: u mit Verkettung: Beim Suchen müssen nur Objekte mit gleichem Schlüsselwert in einer verketteten Liste verglichen werden. n Problem: u Der Zugriff wird mit zunehmender Anzahl der Kollisionen langsamer. u Die Suche kann sogar zur linearen Suche entarten. Ist die zu erwartende Anzahl von Objekten bekannt, kann auch die Lösung mit einer Liste gut sein. n Eine mögliche Lösung: u Einsatz von Bäumen statt Listen.

57 Holger Vogelsang Informatik 2 - Datenstrukturen57 Hashtabellen Hashtabellen mit Verkettung n Nachteile von Hashtabellen mit Verkettung: u Es muss dynamisch Speicher belegt werden, was das Eintragen in die Hashtabelle zu einer relativ aufwändigen Operation macht. u Dynamische Container brauchen mehr Platz als ein statisches Feld mit gleich vielen Elementen. u Bei zunehmender Anzahl der Kollisionen ist Listensuche erforderlich.

58 Holger Vogelsang Informatik 2 - Datenstrukturen58 Hashtabellen Hashtabellen mit Verkettung: Eine einfache Implementierung Implementierung einer sehr einfachen und nicht optimalen Hashtabelle für Schlüssel und Werte eines beliebigen Typs mit Kollisionslisten (Projekt HashMap, Pair überschreibt equals für die Duplikatprüfung beim Einfügen): public class SimpleHashMap implements Iterable.Pair> { // Paar für Schlüssel (K) und Wert (V), normalerweise impl. Interface class Pair { private K key; // + Getter private V value; // + Getter und Setter public Pair(K key, V value) { this.key = key; this.value = public boolean equals(Object otherPair) { if (otherPair != null && otherPair.getClass() == getClass()) { return ((Pair) otherPair).key.equals(key); } return false; }

59 Holger Vogelsang Informatik 2 - Datenstrukturen59 Hashtabellen Hashtabellen mit Verkettung: Eine einfache Implementierung // Vektor mit den Listen, die ihrerseits die Paare aufnehmen private ArrayList > entries; // Größe des Vektors übergeben public SimpleHashMap(int size) { entries = new ArrayList<>(); // Im Vektor alle Listen anlegen for (int i = 0; i < size; ++i) { entries.add(new LinkedList ()); } // Schlüssel "key" und Wert "value" in der Hash-Tabelle ablegen public void put(K key, V value) { int index = indexFor(key.hashCode()); Pair pair = new Pair(key, value); // Eventuell vorhandenes Paar mit id. Schlüssel löschen entries.get(index).remove(pair); entries.get(index).add(pair); }

60 Holger Vogelsang Informatik 2 - Datenstrukturen60 Hashtabellen Hashtabellen mit Verkettung: Eine einfache Implementierung // Wert zu einem Schlüssel auslesen public V get(K key) { int index = indexFor(key.hashCode()); // Die Listen sequentiell durchsuchen for (Pair pair: entries.get(index)) { if (pair.key.equals(key)) { return pair.value; } return null; }

61 Holger Vogelsang Informatik 2 - Datenstrukturen61 Hashtabellen Hashtabellen mit Verkettung: Eine einfache Implementierung /** * Berechnet den Indes aus einem Hashwert. Die Modulo-Berechnung * abs(hashCode % laenge) ist nicht ausreichend, da * der hashCode den Wert Integer.MIN_VALUE * besitzen kann. Der Absolutwert von Integer.MIN_VALUE * ist wiederum Integer.MIN_VALUE, also negativ! hashCode Berechneter Hashwert. Index innerhalb der Tabelle. */ private int indexFor(int hashCode) { int absHashCode = abs(hashCode); if (absHashCode < 0) { absHashCode = 0; } return absHashCode % entries.size(); }

62 Holger Vogelsang Informatik 2 - Datenstrukturen62 Hashtabellen Hashtabellen mit Verkettung: Eine einfache Implementierung // Die Hash-Tabelle benötigt einen Iterator. Der wird // hier etwas anders als in der HashMap des JDK implementiert. // Innere Klasse von SimpleHashMap class HashMapIterator implements Iterator { private int index; private Iterator listIterator; public HashMapIterator() { // Erste nicht-leere Liste finden for (LinkedList list: entries) { if (list.size() > 0) { listIterator = list.iterator(); break; } ++index; }

63 Holger Vogelsang Informatik 2 - Datenstrukturen63 Hashtabellen Hashtabellen mit Verkettung: Eine einfache public boolean hasNext() { // Gibt es überhaupt ein Element? if (index >= 0 && index < entries.size() && listIterator != null) { // Hat die aktuelle Liste ein weiteres Element? if (listIterator.hasNext()) { return true; } // Nächste Liste mit Eintrag suchen int nextIndex = index; while (++nextIndex < entries.size()) { // Hat sie einen Eintrag? if (entries.get(nextIndex).size() > 0) { return true; } return false; }

64 Holger Vogelsang Informatik 2 - Datenstrukturen64 Hashtabellen Hashtabellen mit Verkettung: Eine einfache public Pair next() { // Gibt es überhaupt ein Element? if (index >= 0 && index < entries.size() && listIterator != null) { // Hat die aktuelle Liste ein weiteres Element? if (listIterator.hasNext()) { return listIterator.next(); } // Nächste Liste mit Eintrag suchen while (++index < entries.size()) { // Hat sie einen Eintrag? if (entries.get(index).size() > 0) { listIterator = entries.get(index).iterator(); return listIterator.next(); } throw new NoSuchElementException(); }

65 Holger Vogelsang Informatik 2 - Datenstrukturen65 Hashtabellen Hashtabellen mit Verkettung: Eine einfache Implementierung // Ein Löschen des aktuellen Elementes ist hier nicht implementiert // --> ist etwas public void remove() { throw new UnsupportedOperationException(); } // Methode, um den Iterator der Hash-Tabelle auszulesen. Auch dieses // ist hier anders als in der HashMap des JDK public Iterator iterator() { return new HashMapIterator(); }

66 Holger Vogelsang Informatik 2 - Datenstrukturen66 Hashtabellen Hashtabellen mit Verkettung: Eine einfache Implementierung public class SimpleHashMapTest { public static void main(String[] args) { SimpleHashMap simpleHashMap = new SimpleHashMap<>(31); simpleHashMap.put("Answer", 42); simpleHashMap.put("What?", 66); for (Iterator.Pair> iter = simpleHashMap.iterator(); iter.hasNext();) { SimpleHashMap.Pair pair = iter.next(); System.out.println(pair.getKey() + ": " + pair.getValue()); } for (SimpleHashMap.Pair pair: simpleHashMap) { System.out.println(pair.getKey() + ": " + pair.getValue()); }

67 Holger Vogelsang Informatik 2 - Datenstrukturen67 Hashtabellen Hashtabellen mit Verkettung: Aufwandsabschätzung n Annahmen: u Die Auslastung der Tabelle ist α = N / M. N = Anzahl der Schlüssel, M = Anzahl der Speicherplätze in der Tabelle. u Der Schlüsselbereich S ist uniform, d.h., die Schlüssel werden gleichmäßig auf die Tabelle verteilt. u Die Berechnung der Hashfunktion hat Aufwand O(1). OperationAufwand Einfügen (inkl. Duplikatsuche)O(N), im Mittel θ(α+1) LöschenO(N), im Mittel θ(α+1) Suche, erfolgreichO(N), im Mittel θ(α+1) Suche, erfolglosO(N), im Mittel θ(α+1)

68 Holger Vogelsang Informatik 2 - Datenstrukturen68 Hashtabellen Offene Hashtabellen/Geschlossene Hashtabellen n Ein anderer Ansatz zur Kollisionsbehandlung sind offene Hashtabellen (manchmal auch gesclossene Hashtabellen): u offen: offene Adressierung im Array u geschlossen: Begrenzung der maximalen Schlüssel im Array n Ansatz: Verzicht auf dynamische Verknüpfungen wie Listen etc. n Statt dessen: Ist beim Einfügen der gesuchte Index belegt, so wird ein freier Nachbarindex gesucht und der Wert dort eingetragen. n Zu Bestimmung eines Nachbarindexes existieren verschiedene Ansätze. n Die Suche erfolgt analog: u Zunächst wird durch den Schlüssel ein Index ermittelt. u Steht dort nicht der gesuchte Wert, so werden die Nachbarindizes durchsucht

69 Holger Vogelsang Informatik 2 - Datenstrukturen69 Hashtabellen Offene Hashtabellen: Einfügen // Fiktive Beispielimplementierung einer Hash-Map ohne Duplikatsprüfung public class SimpleHashMap { // Schlüssel- und Wertepaar class Pair { public K key; public V value; public Pair(K key, V value) { this.key = key; this.value = public boolean equals(Object otherPair) { if (otherPair != null && otherPair.getClass() == getClass()) { return ((Pair) otherPair).key.equals(key); } return false; }

70 Holger Vogelsang Informatik 2 - Datenstrukturen70 Hashtabellen Offene Hashtabellen: Einfügen // ArrayList mit den Paaren private ArrayList entries; // Hash-Map in einer vorgegebenen Größe erzeugen public SimpleHashMap(int size) { entries = new ArrayList (size); for (int i = 0; i < size; ++i) { entries.add(null); // jeder Eintrag ist leer }

71 Holger Vogelsang Informatik 2 - Datenstrukturen71 Hashtabellen Offene Hashtabellen: Einfügen // Einfügen ohne Prüfung auf Duplikate (nicht sehr praxisnah). public void put(K key, V value) { int startIndex = abs(key.hashCode()) % entries.size(); int count = 0; int currentIndex = startIndex; boolean finished = false; do { if (entries.get(currentIndex) == null) { // freien Platz gefunden, Paar erzeugen und eintragen entries.set(currentIndex, new Pair(key, value)); finished = true; } else { // berechne nächsten Index count++; currentIndex = (startIndex + nextStep(count)) % entries.size(); } } while (!finished && (count < entries.size())); }

72 Holger Vogelsang Informatik 2 - Datenstrukturen72 Hashtabellen Offene Hashtabellen: Einfügen // Suche nach einem Wert anhand seines Schlüssels public V get(K key) { int startIndex = abs(key.hashCode()) % entries.size(); int count = 0; int currentIndex = startIndex; // Solange suchen, bis ein leerer Eintrag gefunden wurde do { if (entries.get(currentIndex) == null) { return null; } else { // gefunden! if (entries.get(currentIndex).key.equals(key)) { return entries.get(currentIndex).value; } // Berechne nächsten Index count++; currentIndex = (startIndex + nextStep(count)) % entries.size(); } } while (count < entries.size()); return null; }

73 Holger Vogelsang Informatik 2 - Datenstrukturen73 Hashtabellen Offene Hashtabellen: Lineares Sondieren Die Methode int nextStep(int attempt) ermittelt den nächsten zu testenden Eintrag. n Im einfachsten Fall ist nextStep : private int nextStep(int attempt) { return attempt; } n In diesem Fall nennt man die Vorgehensweise auch lineares Sondieren, und für die Testindizes gilt: h 0 = hash(key); h i = (h 0 + i); n Nachteil: Die Schlüssel ballen sich um primäre Schlüssel (Schlüssel, die beim Einfügen nicht kollidieren). Ziel: nextStep sollte so gewählt werden, dass die Schlüssel wiederum gleichmäßig auf die freien Plätze verteilt werden.

74 Holger Vogelsang Informatik 2 - Datenstrukturen74 Hashtabellen Offene Hashtabellen: Quadratisches Sondieren Die Methode nextStep ermittelt den nächsten Eintrag durch eine quadratische Funktion. h 0 = hash(key); h i = (h 0 + i 2 ); n Vorteil: Die Verteilung ist einfach zu berechnen und verhindert im Wesentlichen primäre Ballungen. n Nachteil: Es werden nicht alle Indizes der Hashtabelle berücksichtigt, damit wird u.U. ein freier Eintrag nicht gefunden. n Es wird aber mindestens die halbe Tabelle durchsucht, wenn deren Größe eine Primzahl ist. n Der Nachteil trägt nur dann, wenn die Tabelle relativ voll ist. n In der Praxis sollte man eine Auslastung von max. 50% vorsehen.

75 Holger Vogelsang Informatik 2 - Datenstrukturen75 Hashtabellen Offene Hashtabellen: Doppelte Hashfunktion Die Methode nextStep ermittelt den nächsten Eintrag durch einen Aufruf einer anderen Hashfunktion g. h 0 = hash(key); h i = (h 0 + i * g(key)); n Doppelte Hashfunktionen zeigen das beste Verhalten, wenn die beiden Hashfunktionen hinreichend unabhängig voneinander sind. n Die Wahrscheinlichkeit, dass beide Hashfunktionen den gleichen Wert liefern, sollte also gering sein.

76 Holger Vogelsang Informatik 2 - Datenstrukturen76 Hashtabellen Offene Hashtabellen: Pseudozufallszahlen Nach der Initialisierung durch den Konstruktor liefern sukzessive Aufrufe von nextStep der Reihe nach die Pseudozufallszahlen. n Die Überlaufstrategie mit einem Pseudozufallszahlengenerator leidet auch unter sekundärer Clusterbildung, es sei denn, der Startwert wird vom Schlüssel abhängig gemacht.

77 Holger Vogelsang Informatik 2 - Datenstrukturen77 Hashtabellen Dynamische Hashtabellen n Dynamische Hashtabellen sind in der Lage, sich bei Bedarf automatisch zu vergrößern oder zu verkleinern, ohne dass ein komplettes Neuberechnen der Hashwerte erforderlich ist. n soll hier nicht betrachtet werden (zu kompliziert…)

78 Holger Vogelsang Informatik 2 - Datenstrukturen78 Hashtabellen Vergleich der Verfahren – einige Zahlen n Vorteile der Hashtabelle mit Verkettung: u Sie erlaubt Auslastungen α > 100%. u Sie unterstützt sehr einfach das Löschen. u Ein gegebener Schlüssel wird immer abgespeichert. n Vorteile der offenen Hashtabellen: u Die Zugriffsoperationen sind wesentlich effizienter. u Die Algorithmen sind einfacher zu implementieren. n Konkrete Werte der durchschnittlichen Anzahl von Versuchen für Füllgrade zwischen 60% und 95%: NameAnzahl Versuche bei Füllgrad α 60%70%80%90%95% Kollisionsliste1,00 Lineares Sondieren1,752,173,005,5010,50 Pseudozufallszahlen2,294,018,0523,0259,91

79 Holger Vogelsang Informatik 2 - Datenstrukturen79 Hashtabellen Vergleich der Verfahren – einige Zahlen n Verlauf beim Einfügen

80 Holger Vogelsang Informatik 2 - Datenstrukturen80 Hashtabellen Implementierungen in Java n Es gibt noch weitere Klassen (siehe Folgeseiten)

81 Holger Vogelsang Hashtabellen Implementierungen in Java n Hashtabellenimplementierungen in Java: HashMap : -Ablage von Schlüssel-/Wertepaaren -Schlüsselduplikate sind nicht erlaubt. -Mehrere Iterierungsmöglichkeiten kommen gleich Hashtable : -Ablage von Schlüssel- Wertepaaren -Schlüsselduplikate sind nicht erlaubt. -im Gegensatz zu HashMap thread-sicher -Iterieren wie bei HashMap HashSet : -Ablage von Schlüsseln -Duplikate sind nicht erlaubt. -Iteratorzugriff mit der Methode public Iterator iterator() Informatik 2 - Datenstrukturen81

82 Holger Vogelsang Hashtabellen Implementierungen in Java LinkedHashMap : -Ablage von Schlüssel- Wertepaaren -Schlüsselduplikate sind nicht erlaubt. -Alle Paare sind untereinander durch eine doppelt-verkettete Liste verbunden. Entweder: in Einfügereihenfolge, um diese zu erhalten oder in jeweils aktualisierter Zugriffsreihenfolge beim Lesen, damit die Elemente mit den häufigsten Zugriffen vorne in der Liste stehen Cache! -Iterieren wie bei HashMap LinkedHashSet : -siehe LinkedHashMap und HashSet (nur Schlüssel, verbunden über eine Liste) Informatik 2 - Datenstrukturen82

83 Holger Vogelsang Hashtabellen Implementierungen in Java n Beispiel zum Einsatz einer Hash-Tabelle in einer Server-Anwendung: u Wenn der Browser mit GZIP komprimierte Dateien verarbeiten kann und u wenn der Dateityp nicht ohnehin schon komprimierte Daten enthält u dann komprimiere die Daten vor dem Versand mit GZIP. n Die Hash-Tabelle enthält die Dateiendungen der nicht zu komprimierenden Dateien. n Ausschnitt: private HashSet compressedFileTypes = new HashSet (); // public void doFilter(...) { if (!isGzipSupportedByBrowser(request) || compressedFileTypes.contains(fileType)) { chain.doFilter(request, response); return; } // vor dem Versand komprimieren GzipResponse gzipRespone = new GzipResponse(response); chain.doFilter(request, gzipRespone); gzipResponse.close(); Informatik 2 - Datenstrukturen83

84 Holger Vogelsang Hashtabellen Implementierungen in Java n Maps und Zugriff auf Iteratoren Informatik 2 - Datenstrukturen84

85 Holger Vogelsang Hashtabellen Implementierungen in Java n Es existieren drei Varianten zum Iterieren: Set keySet() : Liefert die Menge aller Schlüssel, über die iteriert werden kann. Die Werte sind nicht direkt zugreifbar. Collection values() : Liefert alle Schlüssel, über die iteriert werden kann. Deren Zuordnung zu den Schlüsseln ist nicht mehr erkennbar. Set > entrySet() : Liefert die Menge aller Schlüssel-/Werte-Paare, über die iteriert werden kann. n Beispiel mit direkter Iterator-Verwendung: HashMap map = new HashMap<>(); // füllen for (Iterator > entryIter = map.entrySet().iterator(); entryIter.hasNext()); ) { Map.Entry entry = entryIter.next(); String key = entry.getKey(); Integer value = entry.getValue(); // … } Informatik 2 - Datenstrukturen85

86 Holger Vogelsang 86 Hashtabellen Weiterer Einsatz von Hashfunktionen n Wozu kann eine Hashfunktion noch dienen? u Berechnung von Prüfsummen, um zu testen, ob eine Nachricht oder Datei verfälscht wurde. u Beispiel: siehe Informatik 2 - Datenstrukturen Datei Hashwert

87 Holger Vogelsang Informatik 2 - Datenstrukturen87 Hashtabellen Weiterer Einsatz von Hashfunktionen u MD5 ist eine 128-Bit Prüfsumme (hier über den Inhalt der Datei): u Algorithmus: siehe

88 Holger Vogelsang Informatik 2 - Datenstrukturen88 Hashtabellen Wahl einer Hashfunktion n Ziel: Gleichmäßige Verteilung der Werte in der Tabelle. n Beispiel für eine schlechte Hashfunktion: u Studenten-Objekte sollen in einer Hashtabelle gespeichert werden. u Jeder Student hat eine 6-stellige Matrikelnummer, die fortlaufend vergeben wird. u Größe der Hashtabelle: u Hashfunktion 1: -Die ersten beiden Stellen der Matrikelnummer bilden den Schlüssel. -Problem: Alle Datensätze eines Jahrganges werden auf sehr wenige Positionen abgebildet. u Hashfunktion 2: -Die letzten beiden Stellen der Matrikelnummer bilden den Schlüssel. -Besser: Die Datensätze verteilen sich gleichmäßiger auf die Tabelle.

89 Holger Vogelsang Informatik 2 - Datenstrukturen89 Hashtabellen Wahl einer Hashfunktion n Einige Hinweise zur Wahl der Hashfunktion: u Integer-Zahlen i: die Zahl i selbst oder i mod 2 n (n ist eine große Primzahl) u Fließkommazahlen: Addition oder andere Verknüpfung von Mantisse und Exponent u Strings: Addition der ASCII/Unicode-Werte einiger/aller Zeichen, eventuell mit einem Faktor gewichtet u Komplexere Objekte: Reduktion auf primitive Datentypen, die Attribute des Objektes sind. Beispiel: public class Rectangle { private int x; private int y; private int w; private int h; } Hashwert aus Verknüpfung der Koordinaten + Größe

90 Holger Vogelsang Informatik 2 - Datenstrukturen90 Hashtabellen Wahl einer Hashfunktion: Beispiele von Java n Die Ermittlung einer guten Hashfunktion wird hier nicht besprochen. Hashfunktionen in Java (Ergebnis ist immer int ): u für einen String s der Länge n: -s[0]*31 (n-1) + s[1]*31 (n-2) s[n-1] -0 für leere Strings u für Byte-, Short- und Integer-Zahlen: -Die Zahl ist der Hashwert. u für Long-Zahlen: -Exklusiv-Oder-Verknüpfung der unteren und oberen 32 Bit -Rückgabe der unteren 32 Bit u für Double-Zahlen: -Umwandlung der Bit-Repräsentation der Zahl in long -Exklusiv-Oder-Verknüpfung der unteren und oberen 32 Bit (um Mantisse und Exponent zu berücksichtigen) -Rückgabe der unteren 32 Bit

91 Holger Vogelsang Informatik 2 - Datenstrukturen91 Hashtabellen Wahl einer Hashfunktion: Beispiele von Java u für Boolesche Werte: -true : false : 1237 für einen Vector bzw. eine List der Länge n: -v[0].hashCode()*31 (n-1) + v[1].hashCode()*31 (n-2) v[n-1].hashCode() -0 für leere Vektoren n Wichtig in Java: Objekte liefern durch Überschreiben der Methode int hashCode() ihren eigenen Hashwert zurück. u Der Wert darf sich bei mehreren Aufrufen der Methode nicht ändern, solange sich das Objekt nicht ändert. Wenn zwei Objekte beim Vergleich mit der equals -Methode gleich sind, so müssen auch ihre Hashwerte identisch sein.

92 Holger Vogelsang Informatik 2 - Datenstrukturen92 Hashtabellen Wahl einer Hashfunktion: Beispiele von Java Beispiel für Klasse java.awt.geom.Rectangle2D (stark vereinfacht!): public abstract class Rectangle2D { private double x; private double y; private double w; private double public int hashCode() { long bits = Double.doubleToLongBits(x); bits += Double.doubleToLongBits(y) * 37; bits += Double.doubleToLongBits(w) * 43; bits += Double.doubleToLongBits(h) * 47; return (((int) bits) ^ ((int) (bits >> 32))); } // Die equals-Methode liefert dann true, wenn // alle x, y, w, h bei beiden Objekten gleich sind. }

93 Holger Vogelsang Typinfo., I/O Annota- tionen Laufzeit- typinfo. Ein-, Ausgabe Entwurf Prinzipien Verbindung von Modulen OSGiSpring Bäume Übersicht Informatik 2 - Datenstrukturen93 Grafische Oberflä- chen ÜbersichtLayoutsWidgets Grafik- operationen Grafik- widgets Effekte, Animationen Offene Punkte Ereignisse Daten- strukturen ADTs Elementare Datenstrukturen Hash- tabellen Bäume GraphenIteratoren Datenstrukturen in Java

94 Holger Vogelsang Informatik 2 - Datenstrukturen94 Bäume Motivation n Was sind Bäume? n Wozu dienen Bäume? n Wie sind die Daten in einem Baum sortiert? n Wie kann ein Baum effizient implementiert werden? n Verschiedene Baumarten für unterschiedliche Einsatzgebiete

95 Holger Vogelsang Informatik 2 - Datenstrukturen95 Bäume Übersicht n Beispiel: Teilebaum eines Autos [Udo Müller, Fachgebiet WI]

96 Holger Vogelsang Informatik 2 - Datenstrukturen96 Bäume Übersicht n Es ergibt sich ein Aufbau der Teile wie bei einem Stammbaum. n Jeder Strich von oben nach unten bedeutet dabei, dass sich das Ausgangsobjekt aus den tiefer liegenden Objekten zusammensetzt. n Zusammengesetzte Objekte können durch einen solchen Baum eindeutig beschrieben werden.

97 Holger Vogelsang Bäume Übersicht n Stammbaum wichtiger Programmiersprachen (bis 2003) [P. Henning, H. Vogelsang (Hrsg.), Handbuch Programmiersprachen] Informatik 2 - Datenstrukturen97

98 Holger Vogelsang Bäume Übersicht n Darstellung von (X)HTML-Seiten im Browser Informatik 2 - Datenstrukturen98 wird im Browser intern durch einen Baum (DOM) repräsentiert

99 Holger Vogelsang Bäume Übersicht n Quelltext-Verwaltung in Eclipse Informatik 2 - Datenstrukturen99 Quelltext wird intern als Baum dargestellt

100 Holger Vogelsang Bäume Übersicht n Dokumentenstruktur Informatik 2 - Datenstrukturen100

101 Holger Vogelsang Bäume Übersicht n Scene Graph von JavaFX: Informatik 2 - Datenstrukturen101 Scene FlowPane Button Group Ellipse Rectangle

102 Holger Vogelsang Informatik 2 - Datenstrukturen102 Bäume Begriffe n Nicht nur für zusammengesetzte Objekte können Bäume verwendet werden. In der Informatik werden Bäume häufig verwendet, um effizient Objekte einzufügen, zu suchen und zu löschen. Begriffsübersicht Blätter (keine Nachfolger) Knoten Wurzel linker Teilbaum rechter Teilbaum rechter Sohn (der Wurzel) linker Sohn (der Wurzel) Kante

103 Holger Vogelsang Informatik 2 - Datenstrukturen103 Bäume Binärer Suchbaum n In dieser Vorlesung werden Bäume mit den folgenden Eigenschaften behandelt: Die Knoten enthalten Werte, die sich vergleichen lassen. In der Praxis wird man für die Schlüssel die equals -Methode überschreiben und Comparable implementieren bzw. einen Comparator übergeben. u Für jeden Knoten gilt, dass er einen eindeutigen rechten Sohn und einen eindeutigen linken Sohn hat (sofern es diesen jeweils gibt). u Der linke Sohn (sofern es ihn gibt) hat immer einen niedrigeren Wert als der rechte Sohn (sofern es ihn gibt). u Der linke Sohn (sofern es ihn gibt) eines Knotens hat immer einen kleineren Wert als der Knoten. u Der rechte Sohn (sofern es ihn gibt) eines Knotens hat immer einen größeren Wert als der Knoten.

104 Holger Vogelsang Informatik 2 - Datenstrukturen104 Bäume Binärer Suchbaum – eine einfache Implementierung Beispielklasse für einen Baum mit Schlüsseln und Werten (siehe Projekt TreeMap ): public class SimpleTreeMap,V> { // Gleiche Paar-Klasse wie in der SimpleHashMap class Pair { public K key; public V value; public Pair(K key, V value) { /*... */ } } // Knoten des Binärbaumes class Node { private Pair data; private Node left; private Node right; public Node(Pair data, Node left, Node right) { /*... */ } // Getter und Setter } // Wurzel des Baums private Node root;

105 Holger Vogelsang Informatik 2 - Datenstrukturen105 Bäume Binärer Suchbaum – Komplettes Durchlaufen n Es gibt mehrere Arten, einen Baum zu durchlaufen: u Preorder: Zuerst wird der Knoten selbst ausgegeben, dann seine Söhne. u Inorder: Zuerst werden der linke Sohn, dann der Knoten selbst, dann der rechte Sohn ausgegeben. u Postorder: Zuerst werden die Söhne des Knotens ausgegeben, dann der Knoten selbst.

106 Holger Vogelsang Informatik 2 - Datenstrukturen106 Bäume Binärer Suchbaum – Traversierung n Preorder: public void dump(Node node) { if (node != null) { System.out.println(node.data.key + " "); dump(node.left); dump(node.right); } n Inorder: public void dump(Node node) { if (node != null) { dump(node.left); System.out.println(node.data.key + " "); dump(node.right); } n Postorder: Analog

107 Holger Vogelsang Informatik 2 - Datenstrukturen107 Bäume Binärer Suchbaum – Traversierung n Preorder, nicht-rekursiv: void dump(Node node) { stack.offer(node); while (stack.size() > 0) { node = stack.pollLast(); System.out.println(node.data.key); if (node.right != null) { stack.offer(node.right); } if (node.left != null) { stack.offer(node.left); }

108 Holger Vogelsang Informatik 2 - Datenstrukturen108 Bäume Binärer Suchbaum – Traversierung und Ausgabe n Levelorder (Queue anstatt Stack): void dump(Node node) { queue.offer(node); while (queue.size() > 0) { node = queue.poll(); System.out.println(node.data.key); if (node.left != null) { queue.offer(node.left); } if (node.right != null) { queue.offer(node.right); }

109 Holger Vogelsang Informatik 2 - Datenstrukturen109 Bäume Binärer Suchbaum – Suche anhand eines Beispiels n Suche nach dem Wert 34: u Enthält der aktuelle Knoten den gesuchten Wert: fertig. u Ist der gesuchte Wert kleiner als der Knotenwert: linker Sohn u Ist der gesuchte Wert größer als der Knotenwert: rechter Sohn

110 Holger Vogelsang Informatik 2 - Datenstrukturen110 Bäume Binärer Suchbaum – Implementierung der Suche n Suchmethode: public V get(K key) { // Start am Wurzelknoten Node searchNode = root; // Solange es noch Knoten gibt und der aktuelle Knoten nicht // dem gesuchten Wert entspricht, suche weiter. while ((searchNode != null) && (!searchNode.data.key.equals(key))) { // Wenn der gesuchte Wert größer als der Wert des Knotens // ist, nimm den rechten Zweig, ansonsten den linken. searchNode = (key.compareTo(searchNode.data.key) > 0) ? searchNode.right: searchNode.left; } return searchNode != null ? searchNode.data.value : null; }

111 Holger Vogelsang Informatik 2 - Datenstrukturen111 Bäume Binärer Suchbaum – Algorithmus zum Einfügen n Vorgehensweise beim Einfügen: u Zunächst wird die Stelle gesucht, an der sich der Wert im Baum befinden sollte. u Ist der Wert schon vorhanden, so wird einfach die Adresse dieses Wertes zurückgegeben. u Ist er nicht vorhanden, so wird ein neuer Knoten erzeugt und dort eingehängt.

112 Holger Vogelsang Informatik 2 - Datenstrukturen112 Bäume Binärer Suchbaum – Einfügen anhand eines Beispiels n Beispiel: Einfügen des Wertes

113 Holger Vogelsang Informatik 2 - Datenstrukturen113 Bäume Binärer Suchbaum – Algorithmus zum Löschen n Die komplizierteste Funktion ist das Löschen aus einem binären Teilbaum. Dazu müssen drei Fälle unterschieden werden: 1.Der zu löschende Knoten hat gar keinen Sohn. Damit kann er direkt gelöscht werden. 2.Der zu löschende Knoten hat genau einen Sohn. Dann wird der Sohn in den aktuellen Knoten kopiert und der Sohn gelöscht. 3.Der zu löschende Knoten hat zwei Söhne. Dann wird im linken Teilbaum der Sohn mit dem größten Wert gesucht und als neuer zentraler Knoten eingefügt (oder im rechten Teilbaum der kleinste Wert).

114 Holger Vogelsang Informatik 2 - Datenstrukturen114 Bäume Binärer Suchbaum – Löschen anhand eines Beispiels n Beispiel: Löschen des Wertes 36 (Fall 1, der Knoten hat keinen Nachfolger) kann direkt gelöscht werden

115 Holger Vogelsang Informatik 2 - Datenstrukturen115 Bäume Binärer Suchbaum – Löschen anhand eines Beispiels n Beispiel: Löschen des Wertes 34 (Fall 2, der Knoten hat einen direkten Nachfolger) ersetzt 34, die alte 36 wird gelöscht 36

116 Holger Vogelsang Informatik 2 - Datenstrukturen116 Bäume Binärer Suchbaum – Löschen anhand eines Beispiels n Beispiel: Löschen des Wertes 42 (Fall 3, der Knoten wird durch das größte Element des linken oder das kleinste des rechten Teilbaums ersetzt das hat immer nur einen direkten Nachfolger) ersetzt 42, die alte 41 wird gelöscht 41

117 Holger Vogelsang Informatik 2 - Datenstrukturen117 Bäume Binärer Suchbaum – Beispielanwendung public class SimpleTreeMapTest { public static void main(String[] args) { SimpleTreeMap simpleTreeMap = new SimpleTreeMap<>(); simpleTreeMap.add("Question", 66); simpleTreeMap.add("Answer", 42); System.out.println(simpleTreeMap.get("Question")); System.out.println(simpleTreeMap.get("Answer??")); }

118 Holger Vogelsang Informatik 2 - Datenstrukturen118 Bäume Binärer Suchbaum – Aufwandsabschätzung Annahme: Der Baum ist nicht balanciert. OperationAufwand Einfügen, sortierte ReihenfolgeO(N) Einfügen, zufällige ReihenfolgeO(N), im Mittel θ(ln N) LöschenO(N), falls degeneriert IndexzugriffO(N) Suche, degeneriertO(N) Suche, optimal eingefügtO(ln N)

119 Holger Vogelsang Informatik 2 - Datenstrukturen119 Bäume Beispiel zum binären Suchbaum n Darstellung eines arithmetischen Ausdrucks als Baum: f = (a - b) * c - (d / b + sin(e)) n Tipp: Klammerungen werden durch die Höhen der Operatorknoten untereinander wiedergegeben.

120 Holger Vogelsang Informatik 2 - Datenstrukturen120 Bäume Balancierter Baum (AVL) – Idee n Ein Baum heißt vollständig, wenn jeder Knoten entweder zwei Söhne hat oder gar keine. n Bei einem solchen Baum wächst die Höhe des Baumes, also der längste Weg beim Suchen, logarithmisch mit der Anzahl der Objekte. n Die Komplexität des Suchens wächst logarithmisch mit der Anzahl der Elemente. n Gegenteil: Auch die lineare, geordnete Liste ist ein Suchbaum, wenn auch ein vollständig entarteter. Die Komplexität des Suchens in einem derart degenerierten Baum wächst linear mit der Anzahl der Elemente. n Zu den gleichen Zahlen kann man unterschiedliche binäre Suchbäume konstruieren.

121 Holger Vogelsang Informatik 2 - Datenstrukturen121 Bäume Balancierter Baum (AVL) – Idee n Beispiel, in dem der Baumaufbau von der Reihenfolge des Einfügens der Elemente abhängt

122 Holger Vogelsang Informatik 2 - Datenstrukturen122 Bäume Balancierter Baum (AVL) – Idee n Ein Baum kann also zur Liste degenerieren. n Problem: In der Praxis sind Suchbäume praktisch nie vollständig ausgeglichen, denn das würde einen sehr großen Aufwand bedeuten. n Lösung: Näherungsweises Ausgleichen eines Baums (Begriff: ausgeglichener Baum). n Die erste Klasse von ausgeglichenen Bäumen waren die AVL-Bäume (nach den Erfindern G. M. Adelson-Velski/E. M. Landis). n Ziel: Je zwei Teilbäume an einem Knoten dürfen sich in der Höhe um nicht mehr als 1 unterscheiden. Dieses gilt für alle Teilbäume an allen Knoten. n Ein Baum ist genau dann ausgeglichen, wenn dieses Ziel erreicht ist.

123 Holger Vogelsang Informatik 2 - Datenstrukturen123 n Nach jeder Einfüge- oder Löschoperation muss überprüft werden, ob ein Ausgleichen des Baums erforderlich ist n Das Ausgleichen erfolgt durch Rotation der Knoten. n Beispiel: Linksrotation um die Knoten B/D. n Eine Linksrotation reduziert die Höhe des rechten Teilbaums um 1 und erhöht die Höhe des linken um 1. Bäume Balancierter Baum (AVL) – Ausgleichen B D Rotationspunkt ec a D B e c a

124 Holger Vogelsang Informatik 2 - Datenstrukturen124 ec Bäume Balancierter Baum (AVL) – Ausgleichen durch Doppelrotation n Um die Höhe eines inneren Baums zu verändern, muss eine Doppelrotation LR oder RL angewendet werden. n Beispiel: Doppelrotation B F a D g ec D F a B g

125 Holger Vogelsang Informatik 2 - Datenstrukturen125 Bäume Balancierter Baum (AVL) – Algorithmus zum Ausgleichen n Gegeben sei ein Baum mit einer Wurzel W sowie deren linken Teilbaum L und rechten Teilbaum R. n Der neue Knoten soll in L eingefügt werden (wie bisher auch). u Höhe(L) = Höhe(R): Nach dem Einfügen unterscheiden sich die Höhen um 1 -> Ausgeglichenheit nicht verletzt. u Höhe(L) < Höhe(R): Die Höhen werden gleich. Die Ausgeglichenheit ist nicht verletzt. u Höhe(L) > Höhe(R): Die Ausgeglichenheit wird zerstört. Der Baum muss restrukturiert werden. n Lösung: Jeder Knoten enthält zusätzlich Balance-Informationen. u Höhe(L) = Höhe(R): balance = 0 u Höhe(L) < Höhe(R): balance = 1; u Höhe(L) > Höhe(R): balance = -1;

126 Holger Vogelsang Informatik 2 - Datenstrukturen126 Bäume Balancierter Baum (AVL) – Beispiel n Aufwandsabschätzung OperationAufwand EinfügenO(ln N) LöschenO(ln N) IndexzugriffO(N) SucheO(ln N)

127 Holger Vogelsang Informatik 2 - Datenstrukturen127 Bäume Balancierter Baum (Top-Down 2-3-4) – Idee n AVL-Bäume sind kompliziert auszugleichen. n Normale binäre Bäume können im schlimmsten Fall zu einer linearen Liste entarten. n Idee: Bäume können an einem Knoten mehr als einen Schlüssel haben. u 2-Knoten (1 Schlüssel)3-Knoten (2 Schlüssel) u 4-Knoten (3 Schlüssel) n < n> n n0n0 < n 0 > n 1 n1n1 > n 0 < n 1 n0n0 < n 0 > n 2 n1n1 > n 0 < n 1 n2n2 > n 1 < n 2

128 Holger Vogelsang Informatik 2 - Datenstrukturen128 Bäume Balancierter Baum (Top-Down 2-3-4) – Suchoperation anhand eines Beispiels n Suche nach dem Wert 15: u Enthält der aktuelle Knoten den gesuchten Wert: fertig. u Wähle das Intervall, in dem der Schlüssel liegen müsste und folge der Kante zum nächsten Knoten

129 Holger Vogelsang Informatik 2 - Datenstrukturen129 Bäume Balancierter Baum (Top-Down 2-3-4) – Einfügeoperation (naiv) Grundidee (ineffizient) n Suche nach dem Blatt-Knoten, in dem der Schlüssel liegen müsste. n Der Knoten ist ein 2-Knoten: Schlüssel einfügen, es entsteht ein 3-Knoten. n Der Knoten ist ein 3-Knoten: Schlüssel einfügen, es entsteht ein 4-Knoten. n Der Knoten ist ein 4-Knoten: u Möglichkeit 1: Den Schlüssel als neues Blatt an den 4-Knoten anhängen Problem: Wie soll ausbalanciert werden? u Möglichkeit 2: Durchführen der folgenden Schritte: 1.Den mittleren Schlüssel des 4-Knotens entnehmen. 2.Den 4-Knoten in zwei 2-Knoten aufspalten. 3.Den neuen Schlüssel in einen der 2-Knoten einfügen. 4.Den mittleren Knoten des ehemaligen 4-Knotens in den Vaterknoten einfügen. 5.Wenn der Vater vorher ein 4-Knoten war auch aufspalten. 6.Im schlimmsten Fall bis zur Wurzel aufspalten.

130 Holger Vogelsang Informatik 2 - Datenstrukturen130 Bäume Balancierter Baum (Top-Down 2-3-4) – Einfügeoperation (effizient) Grundidee (effizient) n Suche nach dem Knoten/Blatt, in dem der Schlüssel liegen müsste. n Teile jeden auf dem Pfad liegenden 4-Knoten in 2 2-Knoten auf (der 2. Durchlauf entfällt dadurch).

131 Holger Vogelsang Informatik 2 - Datenstrukturen131 Bäume Balancierter Baum (Top-Down 2-3-4) – Einfügeoperation (effizient) n Die Wurzel des Baums wird grundsätzlich in 3 2-Knoten aufgeteilt, wenn sie ein 4-Knoten war. n Da die 4-Knoten auf dem Weg von der Wurzel zu den Blättern gespalten werden, spricht man von einem Top-Down-Baum. n Der Baum wächst immer in Richtung Wurzel, daher ist er stets ausbalanciert. Alle Äste wachsen gleichmäßig. n In der Praxis sind relativ wenige Aufspaltungen eines 4-Knotens erforderlich.

132 Holger Vogelsang Informatik 2 - Datenstrukturen132 Bäume Balancierter Baum (Top-Down 2-3-4) – Einfügeoperation anhand eines Beispiels n Einfügen des Wertes 16: Ausgangssituation Einfügen von 16 (vor Teilen der Wurzel)

133 Holger Vogelsang Informatik 2 - Datenstrukturen133 Bäume Balancierter Baum (Top-Down 2-3-4) – Einfügeoperation anhand eines Beispiels Einfügen von 16 (nach Teilen der Wurzel)

134 Holger Vogelsang Informatik 2 - Datenstrukturen134 Bäume Balancierter Baum (Top-Down 2-3-4) – Aufwandsabschätzung Der Baum ist immer balanciert. OperationAufwand Einfügen, sortierte ReihenfolgeO(ln N) Einfügen, zufällige ReihenfolgeO(ln N), im Mittel θ(ln N) LöschenO(ln N) IndexzugriffO(N) SucheO(ln N)

135 Holger Vogelsang Informatik 2 - Datenstrukturen135 Bäume Balancierter Baum (Red-Black) – Idee n Die Implementierung des Einfügens in einen Baum ist leicht ineffizient, da in jedem Schritt geprüft werden muss, ob eine Aufspaltung notwendig ist. n Neue Idee u 3-Knoten und 4-Knoten werden als spezielle kleine binäre Bäume dargestellt, die durch rote Verbindungen verkettet sind. Die schwarzen Verkettungen halten den kompletten Baum selbst zusammen. u Ein zusätzliches Bit im Knoten zeigt an, ob er über eine rote oder eine schwarze Verbindung mit seinen Vater verkettet ist. n Ein Rot-Schwarz-Baum kann als eine spezielle Implementierung des Baums gesehen werden.

136 Holger Vogelsang Informatik 2 - Datenstrukturen136 Bäume Balancierter Baum (Red-Black) – Idee n Umwandlung eines 4-Knotens in einen kleinen Binärbaum: n Umwandlung eines 3-Knotens in einen kleinen Binärbaum:

137 Holger Vogelsang Bäume Balancierter Baum (Red-Black) – Idee n Bedingungen für die Farben: u Jeder Knoten im Baum ist entweder rot oder schwarz eingefärbt. u Die Wurzel des Baums ist immer schwarz. u Alle Blätter sind schwarz. u Ist ein Vaterknoten rot, so sind beide Nachfolger schwarz. u Jeder Pfad von einem beliebigen Knoten zu seinen Blättern enthält die gleiche Anzahl schwarzer Knoten. n Konsequenz: Die Pfadlängen von der Wurzel zu den Blättern kann sich maximal um den Faktor 2 unterscheiden. Warum? u Im kürzesten Pfad sind alle Knoten schwarz. u Im längsten Pfad wechseln sich rote und schwarze Knoten ab. Informatik 2 - Datenstrukturen137

138 Holger Vogelsang Informatik 2 - Datenstrukturen138 Bäume Balancierter Baum (Red-Black) – Aufwandsabschätzung Der Red-Black-Tree soll hier nicht näher betrachtet werden. Der Baum ist immer balanciert. OperationAufwand Einfügen, sortierte ReihenfolgeO(ln N) Einfügen, zufällige ReihenfolgeO(ln N), im Mittel θ(ln N) LöschenO(ln N) IndexzugriffO(N) SucheO(ln N)

139 Holger Vogelsang Informatik 2 - Datenstrukturen139 Bäume Implementierungen in Java n Baum-Klassen

140 Holger Vogelsang Bäume Implementierungen in Java n Baumimplementierungen in Java (Rot-Schwarz-Baum): TreeMap : -Ablage von Schlüssel- Wertepaaren -Schlüsselduplikate sind nicht erlaubt. -Mehrere Iterierungsmöglichkeiten (wie bei HashMap ): public Set > entrySet() liefert die Menge aller Schlüssel/Werte-Paare, über die iteriert werden kann public Set keySet() liefert die Menge aller Schlüssel, über die iteriert werden kann public Collection values() ermittelt alle Werte, über die iteriert werden kann TreeSet : -Ablage von Schlüsseln -Schlüsselduplikate sind nicht erlaubt. -Iteratorzugriff mit der Methode public Iterator iterator() Informatik 2 - Datenstrukturen140

141 Holger Vogelsang Informatik 2 - Datenstrukturen141 Bäume Die Klasse TreeMap: Beispiel Wörterzählen public class TreeMapWordCountTest { // Wörter einlesen. Trennzeichen sind Leerzeichen, // Tabulatoren und Zeilenumbrüche usw. public static TreeMap getWords(String text) { // TreeMap zum sammeln aller Wörter als Schlüssel // sowie deren Anzahl als Wert. TreeMap words = new TreeMap<>(); // Der StringTokenizer zerlegt einen String in einzelne Tokens (Wörter). // Die Worttrennzeichen sind die einzelnen Zeichen im 2. Parameter. StringTokenizer tokenizer = new StringTokenizer(text, " \t\r\n.,;-"); while (tokenizer.hasMoreTokens()) { String input = tokenizer.nextToken(); Integer count = words.get(input); words.put(input, count == null ? 1 : count.intValue() + 1); } return words; }

142 Holger Vogelsang Informatik 2 - Datenstrukturen142 Bäume Die Klasse TreeMap: Beispiel Wörterzählen public static void main(String[] args) { String text = "C++ ist meine absolute Lieblingssprache und" + " ich freue mich auf die Klausur. Eigentlich" + " ist Java meine Lieblingssprache."; TreeMap words = getWords(text); for (Map.Entry wordEntry: words.entrySet()) { System.out.println(wordEntry.getKey() + ": " + wordEntry.getValue()); }

143 Holger Vogelsang Informatik 2 - Datenstrukturen143 Bäume Die Klasse TreeMap: Beispiel Wörterzählen n Eingabe C++ ist meine absolute Lieblingssprache und ich freue mich auf die Klausur. Eigentlich ist Java meine Lieblingssprache. n Alphabetische Ausgabe der Wörter C++: 1 Eigentlich: 1 Java: 1 Klausur: 1 Lieblingssprache: 2 absolute: 1 auf: 1 die: 1 freue: 1 ich: 1 ist: 2 meine: 2 mich: 1 und: 1

144 Holger Vogelsang Informatik 2 - Datenstrukturen144 Bäume Balancierter Baum (B) – Idee eines Mehrwegbaums n B-Bäume sind eine Verallgemeinerung balancierter Bäume. n B-Bäume sind Mehrwegbäume. n Die Ordnung des Baums ist o, o >= 2. u Jeder Knoten enthält maximal 2 * o Schlüssel. u Jeder Knoten hat minimal o Schlüssel. Speicherausnutzung beträgt min. 50% (Ausnahme: Wurzel, die zu weniger als 50% gefüllt sein darf). u Die Schlüssel innerhalb eines Knotens sind aufsteigend sortiert. u Wenn m die Anzahl der Schlüssel in einem Knoten ist, so hat der Knoten genau m + 1 Nachfolger, wenn er kein Blatt ist. u Die Schlüssel des linken Teilbaums sind kleiner als der Schlüssel der Wurzel dieses Teilbaums. u Die Schlüssel des rechten Teilbaums sind größer als der Schlüssel der Wurzel dieses Teilbaums. u Alle Blattseiten liegen auf einer Ebene. n Optional: Neben einem Schlüssel können auch Werte abgelegt sein.

145 Holger Vogelsang Informatik 2 - Datenstrukturen145 Bäume Balancierter Baum (B) – Idee eines Mehrwegbaums n Ein B-Baum der Ordnung 2: n Aufbau eines Knotens ohne Werte (p i = Verweis auf Nachfolger, k i = Schlüssel): n Aufbau eines Knotens mit Werten (p i = Verweis auf Nachfolger, k i = Schlüssel, v i ist Datenwert von Schlüssel k i ): p0p0 …k m-1 k1k1 p1p1 k2k2 p m-1 kmkm pmpm p0p0 …k m-1 k1k1 p1p1 k2k2 p m-1 kmkm pmpm v1v1 v2v2 v m-1 vmvm

146 Holger Vogelsang Informatik 2 - Datenstrukturen146 Bäume Balancierter Baum (B) – Einsatzgebiet n B-Bäume werden häufig zur Verwaltung von Daten auf externen Massenspeichern eingesetzt: u Der Baum enthält Schlüssel und Indizes für die eigentlichen Nutzdaten. u Die Nutzdaten liegen sequentiell in einer eigenständigen Datei vor. u Vorteile dieser Organisation: -Wenn auf die Daten nicht sequentiell zugegriffen werden muss, muss nur der Baum abgesucht werden. Dieser enthält dann die Position der Nutzdaten in der zweiten Datei. -Zum Einfügen und Löschen muss die Reihenfolge der Nutzdaten nicht verändert werden. -Es sind nur sehr wenige Zugriffe notwendig Zugriffe auf den Massenspeicher sind sehr langsam. -Nur der Wurzelknoten des Baums wird im Speicher gehalten. u Ein ähnlicher Aufbau wird für Datenbanken gewählt.

147 Holger Vogelsang Informatik 2 - Datenstrukturen147 Bäume Balancierter Baum (B) – Aufbau bei externem Massenspeicher n Zusammenhang zwischen Index (Baum) und Nutzdatendatei: n Anmerkungen: u Im Beispiel: Schlüssel = Position in der Datei u In der Realität: zusätzlich Nutzdaten mit der Position als Wert Satz 2 … Satz 7 Satz 27 Satz 1 … Satz 42 Satz 3 … usw.

148 Holger Vogelsang Informatik 2 - Datenstrukturen148 Bäume Balancierter Baum (B) – Suchoperation n Funktionsweise der Suchoperation: 1.Startknoten: Wurzel des Baums 2.Suche mittels Binärsuche nach dem Schlüssel. 3.Ist der Schlüssel vorhanden, so ist die Suche beendet. 4.Ermittlung des Nachfolgeknotens: Auswahl des Verweises zwischen den zwei Werten, zwischen denen der Suchschlüssel liegen muss. 5.Wenn ein Nachfolgeknoten existiert (Knoten ist kein Blatt), dann lade den Knoten vom Massenspeicher weiter an Punkt 2. 6.Wenn kein Nachfolgeknoten existiert, so ist der Schlüssel nicht im Baum vorhanden.

149 Holger Vogelsang Informatik 2 - Datenstrukturen149 Bäume Balancierter Baum (B) – Suchoperation am Beispiel n Suche nach dem Schlüssel 35:

150 Holger Vogelsang Informatik 2 - Datenstrukturen150 Bäume Balancierter Baum (B) – Einfügeoperation am Beispiel n Es soll ein Baum durch das Einfügen der folgenden Zahlen entstehen: 20, 40, 10, 30, 15, 35, 7, 26, 18, 22, 5, 42, 13, 46, 27, 8, 32, 38, 24, 45, 25. n Der Baum hat die Ordnung 2. n Einfügen: u Analog zum Top-Down Baum u Das mittlere Element wird nach dem (gedachten) Einfügen ermittelt. 20 Eingefügt: Eingefügt: Eingefügt: Eingefügt: Eingefügt: Eingefügt:

151 Holger Vogelsang Informatik 2 - Datenstrukturen151 Bäume Balancierter Baum (B) – Einfügeoperation am Beispiel Eingefügt: Eingefügt: Eingefügt: Eingefügt:

152 Holger Vogelsang Informatik 2 - Datenstrukturen152 Bäume Balancierter Baum (B) – Einfügeoperation am Beispiel Eingefügt: Eingefügt:

153 Holger Vogelsang Informatik 2 - Datenstrukturen153 Bäume Balancierter Baum (B) – Einfügeoperation am Beispiel Eingefügt: Eingefügt:

154 Holger Vogelsang Informatik 2 - Datenstrukturen154 Bäume Balancierter Baum (B) – Einfügeoperation am Beispiel Eingefügt: Eingefügt:

155 Holger Vogelsang Informatik 2 - Datenstrukturen155 Bäume Balancierter Baum (B) – Einfügeoperation am Beispiel Eingefügt: Eingefügt:

156 Holger Vogelsang Informatik 2 - Datenstrukturen156 Bäume Balancierter Baum (B) – Einfügeoperation am Beispiel Eingefügt: Eingefügt:

157 Holger Vogelsang Informatik 2 - Datenstrukturen157 Bäume Balancierter Baum (B) – Einfügeoperation am Beispiel Eingefügt:

158 Holger Vogelsang Informatik 2 - Datenstrukturen158 Bäume Balancierter Baum (B) – Löschoperation n Löschoperation in einem B-Baum: 1.Unterscheidung zweier Fälle: -Das zu löschende Objekt liegt in einem Blatt. Es wird gelöscht Schritt 2. -Das zu löschende Objekt liegt nicht in einem Blatt: Aus dessen linkem Teilbaum wird das größte Element geholt (oder aus dem rechten Teilbaum das kleinste). Dieses ersetzt das zu löschende Objekt Schritt 2. 2.Ausgleichen: Durch das Löschen der Objekte kann ein Unterlauf auftreten (der Knoten ist nicht mehr zu min. 50% gefüllt). Es werden eine benachbarte Seite geladen und die Elemente auf beide Seiten gleichmäßig verteilt. 3.Tritt dabei ein Unterlauf auf, werden beide Seiten zusammengelegt und das mittlere Element des Vaterknoten in die gemeinsame Seite eingefügt. 4.Jetzt kann im Vaterknoten ein Unterlauf auftreten Schritt 2.

159 Holger Vogelsang Informatik 2 - Datenstrukturen159 Bäume Balancierter Baum (B) – Löschoperation am Beispiel n Es sollen aus dem Baum die folgenden Schlüssel entfernt werden: 25, 45, 24, 38, 32, 8, 27, 46, 13, 42, 5, 22, 18, 26, 7, 35, 15. n Der Baum hat die Ordnung

160 Holger Vogelsang Informatik 2 - Datenstrukturen160 Bäume Balancierter Baum (B) – Löschoperation am Beispiel Gelöscht: Gelöscht:

161 Holger Vogelsang Informatik 2 - Datenstrukturen161 Bäume Balancierter Baum (B) – Löschoperation am Beispiel Gelöscht: Gelöscht:

162 Holger Vogelsang Informatik 2 - Datenstrukturen162 Bäume Balancierter Baum (B) – Löschoperation am Beispiel Gelöscht: Gelöscht:

163 Holger Vogelsang Informatik 2 - Datenstrukturen163 Bäume Balancierter Baum (B) – Löschoperation am Beispiel Gelöscht: Gelöscht:

164 Holger Vogelsang Informatik 2 - Datenstrukturen164 Bäume Balancierter Baum (B) – Löschoperation am Beispiel Gelöscht: Gelöscht:

165 Holger Vogelsang Informatik 2 - Datenstrukturen165 Bäume Balancierter Baum (B) – Löschoperation am Beispiel Gelöscht: Gelöscht:

166 Holger Vogelsang Informatik 2 - Datenstrukturen166 Bäume Balancierter Baum (B) – Löschoperation am Beispiel Gelöscht: Gelöscht: Gelöscht: Gelöscht: Gelöscht: 15

167 Holger Vogelsang Informatik 2 - Datenstrukturen167 Bäume Balancierter Baum (B) – Sequentieller Datenzugriff n Inorder-Durchlauf aller Knoten: n Nachteil: Auf Knoten muss mehrfach zugegriffen werden (Laden vom Massenspeicher!).

168 Holger Vogelsang Informatik 2 - Datenstrukturen168 Bäume Balancierter Baum (B) – Aufwandsabschätzungen n Bedeutung der Ordnung o des Baums: u Je größer o ist, desto flacher wird der Baum u Je kleiner o ist, desto geringer ist der Aufwand zum Suchen innerhalb des Knotens. n Seien u n = Anzahl Knoten im Baum mit n >= 2 u o = Ordnung des Baums mit o >= 1 u Dann gilt für die Höhe h des Baum: h <= log 2*o ((n+1) / 2) n Damit gilt für die Suche eines Schlüssels u Ermittlung und Laden der Seiten entlang des Pfads: O(log 2*o ( (n+1)/2 )) u Suche innerhalb einer Seite mittels Binärsuche: O(ld( 2*o )) n Damit gilt für die komplette Suche: O(log 2*o ((n+1)/2 ))* O(ld( 2*o )), wobei der Aufwand für das Laden einer Seite wegen der Plattenzugriffe deutlich höher als die Suche innerhalb der Seite ist.

169 Holger Vogelsang Informatik 2 - Datenstrukturen169 Bäume Balancierter Baum (B) – Aufwandsabschätzungen n Erste Idee: Ein Knoten soll möglichst viele Elemente enthalten. n Konsequenzen: u Beim rekursiven Abstieg zum Einfügen werden alle gefundenen Knoten im Speicher gehalten, um die Anzahl der Plattenzugriffe klein zu halten. Dadurch wächst bei sehr vielen Knoten der Speicherbedarf an. u Werden die Knoten nicht mehr im Speicher gehalten, so wächst die Zeit für die Plattenzugriffe (Verdopplung). n Bessere Idee: Häufig wird die Knotengröße so gewählt, dass ein Knoten sehr gut beispielsweise in einen Sektor auf dem externen Speicher passt und so effizient gelesen werden kann.

170 Holger Vogelsang Informatik 2 - Datenstrukturen170 Bäume Balancierter Baum (B*) n Der B*-Baum ist eine Abwandlung des B-Baums mit Daten: u Innere Knoten enthalten nur Schlüssel (so genannte Separatorschlüssel) und Nachfolger als Paare (k i, p i ): -p 0 verweist auf einen Knoten mit Schlüsseln kleiner oder gleich k 1. -p i (1 i < m) verweist auf einen Knoten mit Schlüsseln größer als k i und kleiner oder gleich k i+1. -p m verweist auf einen Knoten mit Schlüsseln größer als k m. u Die Werte befinden sich zusammen mit den Schlüsseln nur in den Blättern als Paare (k i, v i ): Die Daten werden in der Sortierreihenfolge der Schlüssel abgelegt. u Alle Blätter werden zu einer doppelt verketteten Liste verbunden (Verweis p, n oben) sehr schnelles sequentielles Durchlaufen aller Daten. u Der Baum wird in der Literatur manchmal auch B+-Baum genannt, teilweise unterscheiden sich B+- und B*-Bäume aber auch in der Literatur… p0p0 …k m-1 k1k1 p1p1 k2k2 p m-1 kmkm pmpm p…k m-1 k0k0 k1k1 kmkm nv0v0 v1v1 v m-1 vmvm

171 Holger Vogelsang Informatik 2 - Datenstrukturen171 Bäume Balancierter Baum (B*) u Jeder innere Knoten hat min. k und max. 2k Einträge (=Ordnung beim B-Baum). u Jeder Blattknoten hat min. k* und max. 2k* Einträge (außer Wurzel). n Wozu? u In den inneren Knoten ist mehr Platz für Schlüssel und Verweise auf Nachfolger Baumhöhe sinkt bei identischer Knotengröße. u Einfaches Sequentielles Durchlaufen der Datenelemente. u B* ist die wichtigste Variante des B-Baums.

172 Holger Vogelsang Informatik 2 - Datenstrukturen172 Bäume Balancierter Baum (B*) – Einfügeoperation n Einfügen: u Ähnlich wie beim B-Baum. 1.Suche den Schlüssel des neuen Datensatzes im Baum führt immer zu einem Blatt, da Daten nur in Blättern gespeichert werden. 2.Füge den neuen Datensatz im Blatt ein. 3.Falls der Knoten überläuft, wird er gespalten (in der Mitte). 4.Beim Spalten wird ein mittlerer Schlüssel (Separatorschlüssel) erzeugt und in den Vaterknoten eingefügt. 5.Der Separatorschlüssel kann im Blatt vorkommen, muss es aber nicht. 6.Beim Überlauf des Vaterknotens: weiter in Schritt 3

173 Holger Vogelsang Informatik 2 - Datenstrukturen173 Bäume Balancierter Baum (B*) – Einfügeoperation am Beispiel n Beispiel: k = 4, k* = 2 n Startsituation (Knoten bestehen aus Schlüssel und zugehörigem Wert): n Schrittweises Einfügen von [30, Hoffmann]: Aufspalten des Knotens und Erzeugung eines Separatorschlüssels (23) in einem neuen gemeinsamen Vaterknoten. Neue Knoten als Liste verketten. Überlauf im Vaterknoten: Rekursiv zur Wurzel hin fortsetzen. 10Vogelsang15Pape20Gmeiner25Nestler 10Vogelsang15Pape20Gmeiner25Nestler 10Vogelsang15Pape20Gmeiner25Nestler30Hoffmann 23 30Hoffmann Überlauf

174 Holger Vogelsang Informatik 2 - Datenstrukturen174 Bäume Balancierter Baum (B*) – Löschoperation, sequentieller Datenzugriff Löschen n Daten werden immer nur in den Blättern gelöscht. n Unterlauf ähnlich wie beim B-Baum soll hier nicht näher betrachtet werden. Sequentieller Datenzugriff n Verzeigerung in den Blattseiten folgen n Vorteil: Auf jeden Blattknoten muss nur einmal zugegriffen werden. Die Nutzdaten befinden sich nur in den Blättern!

175 Holger Vogelsang Informatik 2 - Datenstrukturen175 Bäume Vergleich von B- und B*-Baum n B-Baum: n B*-Baum: Index (mit Schlüsseln und Werten) Index (mit Separator- schlüsseln) Schlüssel mit Werten

176 Holger Vogelsang Informatik 2 - Datenstrukturen176 Bäume Tries (digitale Bäume) n Trie (gesprochen try): Baum zur Speicherung von Zeichenketten eines Dokumentes, um später leicht das Vorhandensein der Texte im Dokument feststellen zu können (retrieval). n Aufbau: u Knoten ist ein Array mit der Größe = Kardinalität des Alphabetes. u Jeder Eintrag enthält einen Verweis auf einen anderen Knoten. u Die Buchstaben werden nicht um Baum gespeichert (Index ergibt Buchstaben). n Aufbau: Alphabet mit 26 Zeichen als Großbuchstaben. ABCDXYZ… ABCDXYZ… ABCDXYZ… ABCDXYZ…

177 Holger Vogelsang Informatik 2 - Datenstrukturen177 Bäume Tries (digitale Bäume) Beispiel (unvollständig): n Probleme: u Ungleichmäßige Verteilung der Daten (viele leere Verweise z.B. für Kombinationen wie XX, XY, YY, YYYZ, …). u Entartung zur Liste möglich. ABCDZ…F… E…R… … Y E…R… … N…T… … E…I… … E…I… … J…N… … G…T… … BenjaminBennetBettinaBrigitteBrittaFredFrieda

178 Holger Vogelsang Informatik 2 - Datenstrukturen178 Bäume Binäre Tries n Ausweg aus dem Problem der ungleichmäßigen Auslastung: u Repräsentation der Zeichenketten als Binärfolge. u Knoten enthält nur noch Nachfolger für 0 und 1. n Weiterhin problematisch: u Entartung zu Listen.

179 Holger Vogelsang Informatik 2 - Datenstrukturen179 Bäume Patricia Bäume n Ziel: Vermeidung des Entartens zu einer Liste. n Lösung: Practical Algorithm to Retrieve Information Coded in Alphanumeric (Patricia). n Idee: u Irrelevante Teile der Zeichenkette werden übersprungen. u Jeder Knoten enthält die Anzahl zu überspringender Zeichen (Trie) oder Bits (bin. Trie). n Beispiel (kompakte Darstellung eines Trie): Oberkante Objektiv Objektmenge Objektmethode e j im n t

180 Holger Vogelsang Informatik 2 - Datenstrukturen180 Bäume Patricia Bäume n Suchen: u Die im Knoten angegebenen Stellen überspringen. u Zum richtigen Nachfolger laufen. n Vorteil: u Kompakte Struktur, schnelleres Durchlaufen (besonders bei langen Wörtern).

181 Holger Vogelsang Typinfo., I/O Annota- tionen Laufzeit- typinfo. Ein-, Ausgabe Entwurf Prinzipien Verbindung von Modulen OSGiSpring Graphen Übersicht Informatik 2 - Datenstrukturen181 Grafische Oberflä- chen ÜbersichtLayoutsWidgets Grafik- operationen Grafik- widgets Effekte, Animationen Offene Punkte Ereignisse Daten- strukturen ADTs Elementare Datenstrukturen Hash- tabellen Bäume Graphen Iteratoren Datenstrukturen in Java

182 Holger Vogelsang Informatik 2 - Datenstrukturen182 Graphen Motivation n Wozu dienen Graphen? n Welche Arten von Informationen können damit modelliert werden? n Wie können Graphen im Speicher abgebildet werden? n Einige wichtige Algorithmen für Graphen.

183 Holger Vogelsang Informatik 2 - Datenstrukturen183 Graphen Idee n Viele Probleme lassen sich allgemein unter Verwendung von Objekten und Verbindungen formulieren: u Darstellung eines Straßennetzes: [https://maps.google.com/]

184 Holger Vogelsang Graphen Idee u Schienennetzplan (KVV): [http://www.kvv.de/fileadmin/user_upload/kvv/dokumente/netz/liniennetz/2013/L0SCHI_DEZ12_Betreiber.pdf] Informatik 2 - Datenstrukturen184

185 Holger Vogelsang Graphen Idee u Oder etwas berühmter (London Tube): [http://www.tfl.gov.uk/assets/downloads/standard-tube-map.gif] Informatik 2 - Datenstrukturen185

186 Holger Vogelsang Graphen Idee u Beziehungen in einem sozialen Netzwerk: [http://blog.iconsultants.eu/2012/10/was-ist-der-facebook-open-graph-und-warum-gibt-es-ihn/] u Netz aller Flugverbindungen u Elektronische Schaltungen aus Komponenten und Verbindungen u Scheduling: Welche Aufgaben hängen von anderen Aufgaben ab? Informatik 2 - Datenstrukturen186

187 Holger Vogelsang Informatik 2 - Datenstrukturen187 Begriffe n Ein Graph ist eine Menge von Knoten und Kanten. n Knoten sind einfache Objekte, die Namen und andere Eigenschaften haben können. n Kanten sind Verbindungen zwischen Knoten. Graphen Begriffe 639 Knoten Kante

188 Holger Vogelsang Informatik 2 - Datenstrukturen188 Graphen Begriffe n Ein Graph ist unabhängig von seiner Darstellung: n Ein Pfad von einem Knoten x zu einem Knoten y ist eine Liste von aufeinander folgenden Knoten, die durch Kanten verbunden sind. n Ein Graph ist zusammenhängend, wenn von jedem Knoten zu jedem anderen Knoten ein Pfad existiert. n Ein Zyklus ist ein Pfad, in dem Anfangs- und Endknoten identisch sind. n Ein Baum ist ein Graph ohne Zyklen. n Ein Gruppe nicht zusammenhängender Bäume wird Wald genannt

189 Holger Vogelsang Informatik 2 - Datenstrukturen189 Graphen Begriffe n Ein Spannbaum ist ein Teilgraph, der alle Knoten enthält sowie die Kanten, die notwendig sind, um einen Baum zu bilden. n Graphen mit wenigen Kanten (E < V log V) werden licht genannt. n Graphen, in denen nur wenige Kanten fehlen, werden dicht genannt. n Gewichtete Graphen: Die Kanten haben Gewichte (Kosten, Entfernungen,...). n Gerichtete Graphen: Die Kanten können nur in einer vorgegebenen Richtung durchlaufen werden (Einbahnstraßen) Graph Spannbaum

190 Holger Vogelsang Informatik 2 - Datenstrukturen190 Graphen Darstellung im Programm n Knoten werden auf ganze Zahlen (Indizes) abgebildet, um sehr effizient darauf zugreifen zu können: u Knoten werden nummeriert. u Der Hashwert des Namens eines Knotens wird als Index verwendet perfekte Hashfunktion. n Einfachste Darstellung eines Graphen: Adjazenzmatrix (Nachbarschaftsmatrix): u Annahme: Der Graph hat V Knoten. Es wird ein Feld (zweidimensionales Array) graph der Größe V*V mit Booleschen Werten gefüllt: -Der Wert graph[ x ][ y ] = true, wenn eine Kante von Knoten x zu Knoten y führt. -Der Wert graph[ x ][ y ] = false, wenn es diese Kante nicht gibt. -Die Matrix ist symmetrisch für ungerichtete Graphen: graph[ x ][ y ] = graph[ y ][ x ] Speicherplatzverschwendung, aber einfachere Algorithmen

191 Holger Vogelsang Informatik 2 - Datenstrukturen191 Graphen Darstellung im Programm -In der Regel ist es praktisch zu definieren, dass ein Knoten immer zu sich selbst führt: graph[ x ][ x ] = true abhängig vom Einsatz des Graphen n Beispiel: Löschen eines Knotens x : An den Positionen [ 0...V-1 ][ x ] und [ x ][ 0...V-1 ] muss false eingetragen werden (Löschen der Kanten) tffffttf 1fttffftf 2fttftfff 3ffftttft 4fftttttf 5tfftttff 6ttfftftf 7ffftffft

192 Holger Vogelsang Informatik 2 - Datenstrukturen192 Graphen Darstellung im Programm n Beispielgraph:

193 Holger Vogelsang Informatik 2 - Datenstrukturen193 Graphen Darstellung im Programm n Aufwand Adjazenzmatrix: O(V 2 ) Speicherplätze sowie O(V 2 ) Schritte zur Initialisierung. n Nachteil der Adjazenzmatrix: Bei lichten Graphen ist die Speicherplatzverschwendung sehr hoch. n Für lichte Graphen existiert daher eine Adjazenzliste (Nachbarschaftsliste, auch Adjazentstruktur): u Für jeden Knoten werden alle mit ihm verbundenen Knoten in einer Liste gehalten. u Die Listen liegen in einem eindimensionalen Array. n Beispiel:

194 Holger Vogelsang Informatik 2 - Datenstrukturen194 Graphen Darstellung im Programm Ein Kante, die Knoten x mit Knoten y verbindet, wird in der Liste von Knoten x und in der Liste von Knoten y aufgeführt effiziente Suche: Mit welchen Knoten ist Knoten x verbunden? n Vorteil Speicherbedarf: O(V+E), Initialisierung: O(V) n Nachteile: u Einige Algorithmen sind aufwändiger und ineffizienter zu implementieren. Das Löschen eines Knotens x ist aufwändig: In allen Listeneinträgen von x den Knoten x löschen, dann alle Listeneinträge von x löschen. n Konsequenz: Keine direkte Darstellung eines Graphen im Speicher, da der Aufwand für Algorithmen sonst sehr hoch wird.

195 Holger Vogelsang Informatik 2 - Datenstrukturen195 Graphen Darstellung gerichteter und gewichteter Graphen im Programm Gerichtete Graphen n Jede Kante wird nur einmal dargestellt. Darstellung einer Kante von Knoten x zu Knoten y : Adjazenzmatrix: graph[ x ][ y ] = true. Adjazenzliste/Adjazenzstruktur: y erscheint in der Liste von x. Gewichtete Graphen n Die Darstellung erfolgt wie bei ungerichteten Graphen mit den folgenden Erweiterungen: Adjazenzmatrix: Anstelle von true steht in graph[ x ][ y ] der numerische Wert (die Gewichtung) der Kante. Anstelle von false wird eine nicht benutzte Gewichtung eingetragen (z.B. -1 ). u Adjazenzliste/Adjazenzstruktur: Die Liste enthält für jeden Eintrag ein weiteres Feld mit der Gewichtung.

196 Holger Vogelsang Informatik 2 - Datenstrukturen196 Graphen Tiefensuche n Tiefensuche: systematisches Besuchen aller Knoten und Kanten im Graphen n Der Algorithmus ist Basis vieler anderer Lösungen im Zusammenhang mit Graphen. n Ablauf: Ein Feld visitedNodes nimmt für alle Knoten den Index in der Besuchsreihenfolge auf. Wurde der Knoten noch nicht besucht, so enthält es die Konstante UNSEEN (z.B. -1 ). Solange es noch unbesuchte Knoten k i gibt, wird der nächste unbesuchte aus visitedNodes genommen: -In visitedNodes erhält der Knoten k i den nächsten Index. -Es werden alle von k i aus erreichbaren Knoten besucht, die bisher noch nicht besucht wurden.

197 Holger Vogelsang Informatik 2 - Datenstrukturen197 Graphen Tiefensuche V ist die Anzahl der Knoten private int[] visitedNodes = new int[ V ]; private int visitId; private static final int UNSEEN = -1; public void visitNodes() { visitId = 0; // Reihenfolgearray löschen for (int i = 0; i < V; ++i) { visitedNodes[ i ] = UNSEEN; } // Knoten besuchen for (int i = 0; i < V; ++i) { if (visitedNodes[ i ] == UNSEEN) { visitNode(i); }

198 Holger Vogelsang Informatik 2 - Datenstrukturen198 Graphen Tiefensuche Tiefensuche bei Darstellung mit Adjazenzmatrix Der Graph liegt im zweidimensionalen Array graph. n Rekursives Besuchen aller Knoten, die mit dem übergebenen Knoten verbunden sind: public void visitNode(int nodeIndex) { visitedNodes[ nodeIndex ] = ++visitId; // Alle Zellen der Zeile des Knotens absuchen for (int i = 0; i < V; ++i) { if (graph[ nodeIndex ][ i ] && (visitedNodes[ i ] == UNSEEN)) { visitNode(i); } n Zeitaufwand für die Tiefensuche: O(V 2 ), da jedes Bit in der Matrix geprüft wird.

199 Holger Vogelsang Informatik 2 - Datenstrukturen199 Graphen Tiefensuche n Beispiel (siehe Tafelanschrieb):

200 Holger Vogelsang Informatik 2 - Datenstrukturen200 Graphen Tiefen- und Breitensuche Hinweise n Die Rekursion kann genau wie bei Bäumen durch eine Iteration unter Verwendung einer Stack-Klasse implementiert werden. n Wird der Stack durch eine Schlange (Queue) ersetzt, so ergibt sich automatisch Breitensuche. n Unterschiede zwischen Breiten- und Tiefensuche: u Tiefensuche: Es werden erst die Pfade zu den am weitesten entfernt liegenden Knoten gesucht. Erst im Fall einer Sackgasse werden näher liegende Knoten besucht. u Breitensuche: Erst werden alle Knoten in der Nähe und danach immer weiter weg liegende Knoten betrachtet.

201 Holger Vogelsang Informatik 2 - Datenstrukturen201 Graphen Breitensuche iterativ n Der folgende Ausschnitt zeigt eine iterative Lösung zur Breitensuche im Graphen. private int[] visitedNodes = new int[ V ]; private static final int UNSEEN = -1; public void breadthFirstSearch(int startNode) { int visitId = 0; // Breitensuche mit Queue // Tiefensuche mit Deque (als Stack) Queue queue = new LinkedList<>(); // Reihenfolgearray löschen for (int i = 0; i < V; ++i) { visitedNodes[ i ] = UNSEEN; } queue.offer(startNode); while (!queue.isEmpty()) { // Vordersten Knoten der Queue besuchen int node = queue.poll(); // Tiefensuche: queue.pollLast();

202 Holger Vogelsang Informatik 2 - Datenstrukturen202 Graphen Breitensuche iterativ if (visitedNodes[ node ] == UNSEEN) { visitedNodes[ node ] = ++visitId; // Alle Zellen der Zeile des Knotens absuchen for (int i = V - 1; i >= 0; --i) { if (graph[ node ][ i ] && (visitedNodes[ i ] == UNSEEN)) { queue.offer(i); }

203 Holger Vogelsang Informatik 2 - Datenstrukturen203 Graphen Suche des kürzesten Pfades iterativ n Der Breitensuchalgorithmus kann sehr leicht zur Suche des kürzesten Pfades zwischen zwei Knoten verwendet werden: Statt der Reihenfolge der Besuche wird in predNodes der Vorgänger jedes Knotens abgelegt. u Der Algorithmus bricht ab, wenn das Ziel erreicht ist. n Algorithmus: private boolean[] visitedNodes = new boolean[ V ]; private int[] predNodes = new int[ V ]; private final static int UNSEEN = -1; public boolean pathfinder(int startNode, int endNode) { LinkedList queue = new LinkedList<>(); // Reihenfolgearray löschen for (int i = 0; i < V; i++) { visitedNodes[ i ] = false; predNodes[ i ] = UNSEEN; } queue.offer(startNode);

204 Holger Vogelsang Informatik 2 - Datenstrukturen204 Graphen Suche des kürzesten Pfades iterativ while (!queue.isEmpty()) { // Vordersten Knoten der Queue besuchen int node = queue.pollFirst(); if (!visitedNodes[ node ]) { visitedNodes[ node ] = true; // Fertig ? if (node == endNode) { return true; } // Alle Zellen der Zeile des Knotens absuchen for (int i = V - 1; i >= 0; i--) { if (graph[ node ][ i ] && !visitedNodes[ i ] && predNodes[ i ] == UNSEEN) { predNodes[ i ] = node; // jetzigen als Vorgänger eintragen queue.offer(i); } return false; }

205 Holger Vogelsang Graphen Suche des kürzesten Pfades in einem gewichteten Graphen n Suche des kürzesten Pfades in einem gerichteten (nicht so wichtig) und gewichteten Graphen mit nicht-negativen Gewichten mittels Dijkstra-Algorithmus (gehört zu den Greedy- Alghorithmen wählen schrittweise in jedem Zustand den aussichtsreichsten Folgezustand aus) n Zeitaufwand (abhängig von der Darstellung des Graphen im Speicher): min. O(V 2 + E) Informatik 2 - Datenstrukturen

206 Holger Vogelsang Graphen Suche des kürzesten Pfades in einem gewichteten Graphen n Ablauf: 1.Alle Knoten erhalten die Attribute aktuelle Distanz zum Startknoten (Distanz) und Vorgängerknoten im Pfad (Vorgänger). 2.Die Distanzen werden mit (unendlich) initialisiert. Nur der Startknoten erhält zu sich selbst die Distanz 0. 3.Solange es noch unbesuchte Knoten k i gibt, wird derjenige mit dem geringsten Abstand zum Startknoten gewählt (verspricht am ehesten Erfolg): 1.Markiere diesen Knoten k i als schon besucht 2.Berechne für alle Knoten k x, die von k i aus erreichbar sind, die Abstände zum Startknoten als: Abstand k x = Abstand k i + Gewichtung von k i zu k x 3.Ist der berechnete Abstand k x kleiner als der bisherige Abstand zu k x, dann wurde ein kürzerer Pfad zu k x gefunden: a.Trage den neuen Abstand k x am Knoten k x ein und merke als Vorgänger von k x den Knoten k i. b.Trage k i als Vorgänger von k x ein. n Java-Code: siehe Eclipse-Projekt GraphAlgos. Informatik 2 - Datenstrukturen206

207 Holger Vogelsang Informatik 2 - Datenstrukturen207 Graphen Weitere Algorithmen n Es existieren viele weitere Algorithmen für Graphen, die in der Praxis sehr wichtig sind: u Kürzeste Pfade zwischen allen Knoten, kürzester Pfad von einem Knoten zu allen anderen, … u Kürzeste Menge der Linien, die alle Punkte innerhalb einer Ebene verbinden. u Topologisches Sortieren eines azyklischen, gerichteten Graphen: Erst werden die Knoten ermittelt, auf die kein anderer Knoten verweist. Dann die Knoten, auf die nur bereits im ersten Schritt ermittelte Knoten verweisen... Abhängigkeitsgraph. n Diese Algorithmen sollen nicht mehr Bestandteil der Vorlesung sein.

208 Holger Vogelsang Graphen Bibliotheken n Für die Verwendung von Graphen in Java existieren eine ganze Anzahl unterschiedlicher Bibliotheken. Interessant sind: u JGraphT (http://www.jgrapht.org/): Frei verfügbare Bibliothek mit Graphenalgorithmenhttp://www.jgrapht.org/ u JGraph (http://www.jgraph.com/jgraph.html): Frei verfügbare Bibliothek zur Darstellung von Graphen (z.B. denen von JGraphT)http://www.jgraph.com/jgraph.html Beispiel zur Suche des kürzesten Pfades in einem Graphen (Projekt GraphDemo ): // Gerichteter Graph ListenableGraph g = new ListenableDirectedGraph(DefaultEdge.class); // Knoten ergänzen g.addVertex("v1"); g.addVertex("v2"); g.addVertex("v3"); g.addVertex("v4"); // Knotenverbinden g.addEdge("v1", "v2"); g.addEdge("v2", "v3"); g.addEdge("v3", "v1"); g.addEdge("v4", "v3"); List result = DijkstraShortestPath.findPathBetween(g, "v1", "v4"); Informatik 2 - Datenstrukturen208


Herunterladen ppt "Informatik 2 Datenstrukturen Prof. Dr.-Ing. Holger Vogelsang"

Ähnliche Präsentationen


Google-Anzeigen