Was bisher geschah I Algorithmen I Spezifikation I asymptotische Laufzeit von Algorithmen (O-Notation) I Sortier-Algorithmen I rekursive Algorithmen I Divide-and-Conquer-Algorithmen I Dynamische Programmierung 75 Entwurfsebenen Mathematik: Algorithmik: Programmierung: Funktion ↓ Algorithmus ↓ (Unter-)Programm Methode Abstrakter Datentyp ↓ Algebra (Konkreter Datentyp) ↓ Datenstruktur ↓ Datentyp Klasse 76 Motivation ADT Aufgabe: Verwaltung einer Menge ganzer Zahlen, so das festgestellt werden kann, ob eine Zahl darin enthalten ist und Zahlen hinzugefügt und entfernt werden können. Spezifikation des Datentyps NSet muss enthalten: I I N N Wertebereiche (Sorten): , Mengen ⊆ , Wahrheitswerte (Bool) Operationen: finden, hinzufügen, entfernen Operationen mit Typdeklaration N N contains : Menge × → add, remove : Menge × → isempty : Menge → emptyset : I Bool Menge Bool Menge Bedeutung der Operationen t falls x ∈ M contains(M, x) = f sonst add(M, x) = M ∪ {x} remove(M, x) = M \ {x} = ∅ t falls M = ∅ isempty(M) = f sonst emptyset 77 Spezifikation durch abstrakte Datentypen (ADT) Abstrakter Datentyp NSet: Sorten: N, Mengen ⊆ N, Wahrheitswerte (Bool) Signatur: Operationen mit Typdeklaration N N contains : Menge × → add, remove : Menge × → isempty : Menge → emptyset : Bool Menge Bool Menge Axiome: formale Beschreibung der Bedeutung der Operationen (Zusammenhänge dazwischen) N ∀s ∈ Menge ∀n ∈ N ∀s ∈ Menge ∀n ∈ N ∀s ∈ Menge ∀m, n ∈ N ∀s ∈ Menge ∀n ∈ N ∀n ∈ isempty((emptyset) = t : contains(emptyset, n) = f : contains(add(s, n), n) = t : contains(remove(s, n), n) = f : add(add(s, n), m) = add(add(s, m), n) : add(add(s, n), n) = add(s, n) ... 78 Abstrakte und konkrete Datentypen Abstrakter Datentyp (ADT): (formale Spezifikation) I Menge von Sorten I (mehrsortige) Signatur ΣF I Menge von Axiomen Φ ADT = (funktionale) Signatur ΣF + Axiome Φ (Interface + Axiome) Konkreter Datentyp: ΣF -Algebra A mit A ∈ Mod(Φ) (Struktur mit geeigneten Funktionen, so dass alle Axiome erfüllt sind) (Implementierung) 79 Beispiel: ADT Boolesche Algebra Abstrakter Datentyp Boolesche Algebra: Sorten: Bool (zwei Wahrheitswerte) Signatur: t: f: ¬: Bool → ∨ : Bool × Bool → ∧ : Bool × Bool → Bool Bool Bool Bool Bool Axiome: ∀a∀b : a ∧ b = b ∧ a, ∀a∀b : a ∨ b = b ∨ a, ∀a∀b∀c : a ∨ (b ∧ c) = (a ∨ b) ∧ (a ∨ c), Φ= ∀a∀b∀c : a ∧ (b ∨ c) = (a ∧ b) ∨ (a ∧ c), ¬(t = f), ∀a∀b : ¬(¬a ∨ b) ∨ ¬(¬a ∨ ¬b) = a passende konkrete Datentypen, z.B. I ({0, 1}, max, min, x 7→ 1 − x, 0, 1) I (2{d} , ∪, ∩, , ∅, {d}) 80 Mehrsortige Strukturen Modellierung von Strukturen mit S = {Si | i ∈ I} von Elementen I verschiedenen Sorten (Mengen) I Operationen auf Elementen der Sorten I Eigenschaften und Zusammenhänge zwischen Operationen Beispiele: I Mengen (Elemente, Mengen von Elementen, polymorph) Operationen: add, contains, empty Zusammenhänge: ∀e ∀l : empty(add(e, l)) = false I Folgen (Elemente, Folgen von Elementen, polymorph) Operationen: add, remove, append, add, reverse Zusammenhänge: ∀l : reverse(reverse(l)) = l I Vektorraum (Skalare, Vektoren) Operationen: smult,sprod,+,0,0v Zusammenhänge: ∀v : smult(0,v) = 0 81 Einfache und zusammengesetzte Datentypen Datentyp: Menge von Werten mit Operationen auf diesen Werten I einfache Datentypen, z.B. int, bool, float, ... I zusammengesetzte Datentypen Konstruktion durch die Operationen I I I I kartesisches Produkt von Datentypen: mehrfaches Produkt desselben Typs, z.B. Tupel Produkt verschiedener Typen, z.B. Klassen, record Vereinigung von Datentypen (in Java: Interface mit mehreren Implementierungen) rekursive Datentypen, z.B. Liste, Term Abbildung zwischen Datentypen (Funktionen) Datenstrukturen: zusammengesetzte Datentypen zur Verwaltung mehrerer Daten desselben Typs 82 Einige prominente Datenstrukturen Mengen typische Operationen: I Test auf Leerheit I Einfügen, Entfernen von Elementen I Suche nach Element I Vereinigung, Durchschnitt, Differenz Folgen (z.B. Listen, Texte), typische Operationen: I Einfügen, Entfernen von Elementen I Suche nach Element I spezielle Elemente suchen (Min, Max, Median) I Sortieren I Verketten, Spiegeln, Teilfolgen bilden, finden Abbildungen (z.B. Wörterbücher), typische Operationen: I Einfügen, Entfernen von Argument-Wert-Paaren I Suche nach dem Wert zu einem Argument Graphen typische Operationen: I Einfügen, Entfernen von Knoten und Kanten I Suche nach Knoten I Suche nach Pfaden (z.B. kürzeste) I Suche nach Teilgraphen (z.B. Gerüst) 83 Beispiel ADT Folge Ziel: Datentyp zur Verwaltung einer endlichen Folge von Elementen einen Typs a (Zuordnung f : {1, . . . , n} → a) mit Operationen zum Bestimmen der Länge der Folge, Hinzufügen und Lesen eines Elementes an einer bestimmten Position. Sorten: Element, Folge von Elementen (polymorph), Bool, Nat Signatur: nil : Folge isempty : Folge → Bool add : Folge × Element → Folge get : Folge × Nat → Element size : Folge → Nat weitere sinnvolle Operationen für Folgen: head : Folge → tail : Folge → reverse : Folge → remove : Folge × Element → append : Folge × Folge → Element Folge Folge Folge Folge Axiome: ? (Tafel) 84 (Ein möglicher) konkreter Datentyp für Folgen N N Sorten: Bool: {0, 1}, Nat: , Element: {a, b, c}, Folge: {(x1 , . . . , xn ) | n ∈ ∧ ∀i ∈ {1, . . . , n} : xi ∈ {a, b, c}} Realisierung der Operationen: nil = () t falls x = () f sonst isempty(x) = add((x1 , . . . , xn ), y ) = (y , x1 , . . . , xn ) get((x1 , . . . , xn ), i) = xi size(x1 , . . . , xn ) = n Nachweis der Gültigkeit der Axiome: (Tafel) 85 Realisierung zusammengesetzter Typen (Verwaltung mehrerer Daten derselben Art) I lineare Datenstrukturen, z.B. Folge, Liste, Queue, Stack I hierarchische Strukturen, z.B. Bäume I Relationen, z.B. Graphen 86 Realisierungen des ADT Menge einige Möglichkeiten: I ungeordnete Folge (Aufzählung aller Elemente) I geordnete Folge (sortierte Aufzählung aller Elemente) I Bitvektor (charakteristische Funktion, {min, . . . , max}) I Speicherplatzbedarf ? asymptotische Laufzeit der Operationen ? I I I I I isempty contains add remove 87 ADT Folge mit Positionszugriff Idee: I fester Speicherplatzbedarf I effizienter Zugriff auf Elemente nach Position ADT PFolge (Spezifikation): Sorten: Element, Folge von Elementen (polymorph), Bool, Nat, Pos Signatur: nil : isempty : Folge → get : Folge × Pos → set : Folge × Element × Pos → remove : Folge × Pos → size : Folge → Folge Bool Element Folge Folge Nat Axiome z.B. isempty(nil) = t, ∀l ∈ Folge ∀y ∈ Element ∀i ∈ Pos : get(set(l, y , i), i) = y 88 Modell für Folgen mit Positionszugriff Trägermengen: Element E, Folgen: E ∗ nil = ε t falls n = 0 isempty(x1 · · · xn ) = f sonst xi falls i ≤ n get(x1 · · · xn , i) = undef sonst set(x1 · · · xn , y , i) = remove(x1 · · · xn , i) = size(x1 · · · xn ) = x1 · · · xi−1 , y , xi+1 , . . . , xn x1 · · · xi−1 ◦ xi+1 · · · xn undef falls i ≤ n sonst n Implementierung z.B. als Array (hinreichender Größe) 89 Realisierung des ADT Folge (mit Positionszugriff) durch verkettete Liste: I isempty O(1) I add O(1) (am Anfang anfügen) I contains O(n) (ein Vorkommen finden) I remove O(n) (alle Vorkommen finden) I get, set O(n) (Position finden) durch Array (variabler Länge): I isempty O(1) I add O(1) (am Ende anfügen) I contains O(n) (ein Vorkommen finden) I remove O(n) (alle Vorkommen finden und Nachrücken) I get, set O(1) (Direktzugriff über Index) 90 ADT Folge ohne Positionszugriff Ziel: I variabler Speicherplatzbedarf (möglichst gering) ADT Folge (Spezifikation, Auszug): Sorten: Bool, Element, Folge, Nat Signatur: nil : isempty : Folge → head : Folge → tail : Folge → add, remove : Folge × Element → append : Folge × Folge → reverse : Folge → size : Folge → Folge Bool Element Folge Folge Folge Folge Nat Axiome z.B isempty(nil) = t ∀x ∈ Folge∀e ∈ Element : isempty(add(e, x)) = f ∀x ∈ Folge∀e ∈ Element : head(add(e, x)) = e ∀x ∈ Folge∀e ∈ Element : tail(add(e, x)) = x 91 Modell für Folgen ohne Positionszugriff Trägermengen: Element E, Folgen: E ∗ nil = ε isempty(x1 · · · xn ) = head(x1 · · · xn ) = tail(x1 · · · xn ) = t falls n = 0 f sonst x1 falls n > 0 undef sonst x2 · · · xn falls n > 0 undef sonst add(e, x1 · · · xn ) = ex1 · · · xn append(x1 · · · xn , y1 · · · ym ) = x1 · · · xn ◦ y1 · · · ym reverse(x1 · · · xn ) = xn · · · x1 size(x1 · · · xn ) = n 92 Rekursive Datentypen Wiederholung: Funktion f heißt rekursiv gdw. in der Definition von f kommt f selbst vor. analog: ADT heißt genau dann rekursiv, wenn er in seiner Definition selbst vorkommt. Jeder induktiv definierte Datentyp (z.B. Listen, Terme, Formeln) ist rekursiv. Operationen in rekursiven Datentypen lassen sich rekursiv realisieren. 93 Beispiel: Einfach verkettete Liste Struktur einer einfach verketteten Liste l ∈ List<E> (mit Elementen vom Typ E): IA: l = nil oder IS: l = Knoten node(head, tail) mit I I head (∈ E) und Liste tail (∈ List<E>) ListhEi = {nil} ∪ (E × ListhEi)} Knotentyp E × ListhEi (mit Element vom Typ E): I Element (head) und I (Verweis auf) Liste (tail) Realisierung der Operationen (contains, remove, . . . ) durch rekursive Funktionen 94