Was bisher geschah I Algorithmen I I I I I Spezifikation rekursive Algorithmen asymptotische Laufzeit Sortieren von Folgen Datentypen I I Abstrakter Datentyp (Spezifikation, Interface): (funktionale) Signatur ΣF + Axiome Φ Konkreter Datentyp (Realisierung, Implementierung): ΣF -Algebra, die alle Axiome aus Φ erfüllt (d.h. Modell für Φ ist) I Abstrakte Datentypen (Interface) konkrete Datentypen (Implementierung) I Beispiele: ADT für Bool, Mengen, Folgen I rekursive Datentypen I lineare Datenstrukturen: Listen 95 Wiederholung ADT ADT für Himmelsrichtungen Norden, Osten, Süden, Westen mit Operationen für Rechts- und Linksabbiegen und Umlenken Spezifikation des ADT Himmelsrichtungen: Sorten: Himmelsrichtung (HR) = {N, O, S, W} Signatur: N, O, S, W : rechts, links, um : HR → HR HR Axiome: rechts(N) = O, links(N) = W, um(N) = S, . . . ∀h ∈ HR : rechts(links(h)) = h, ∀h ∈ HR : links(rechts(h)) = h, ∀h ∈ HR : rechts(rechts(h)) = um(h), . . . 96 Wiederholung ADT Menge Sorten: E, MengehEi, Bool Signatur: Emptyset : isEmpty : MengehEi → contains : MengehEi × E → add, remove : MengehEi × E → MengehEi Bool Bool MengehEi Axiome: isEmpty((Emptyset) = t ∀e ∈ E : contains(Emptyset, e) = f ∀s ∈ MengehEi ∀e ∈ E : contains(add(s, e), e) = t ∀s ∈ MengehEi ∀e ∈ E : contains(remove(s, e), e) = f ∀s ∈ MengehEi ∀e, f ∈ E ∀s ∈ MengehEi ∀e ∈ E : add(add(s, e), f ) = add(add(s, f ), e) : add(add(s, e), e) = add(s, e) ... 97 Wiederholung ADT Folge Sorten: E, FolgehEi, Bool, für Folgen mit Positionszugriff zusätzlich: Pos Signatur: Nil : isEmpty : FolgehEi → contains : FolgehEi × E → add, remove : FolgehEi × E → FolgehEi Bool Bool FolgehEi für Folgen mit Positionszugriff zusätzlich: get : FolgehEi × Pos → E update : FolgehEi × E × Pos → FolgehEi Axiome: isEmpty((Nil) = t ∀l ∈ FolgehEi ∀y ∈ E ∀i ∈ Pos : get(update(l, e, i), i) = e ... 98 Wiederholung: Einfach verkettete Liste Struktur einer einfach verketteten Liste l ∈ ListhEi (mit Elementen vom Typ E): IA: leer: l = Nil oder IS: Knoten l = Node(head, tail) mit I I head ∈ E und Liste tail ∈ ListhEi ListhEi = {Nil} ∪ (E × ListhEi) Knotentyp E × ListhEi (mit Element vom Typ E): I Element (head) und I (Verweis auf) Liste (tail) (Operationen head,tail zum Zugriff auf diese Komponenten) Implementierung des ADT Menge durch Listen: Realisierung der Operationen I offensichtlich: Nil, head, tail, add I rekursiv: contains, remove, get, update (sortiertes Einfügen, Länge) 99 Einfach verkettete Liste – contains Bezeichnung: für l ∈ ListhEi ist Inhalt(l) ⊆ 2E definiert durch I Inhalt(Nil) = ∅ I Inhalt(Node(e, l)) = {e} ∪ Inhalt(l) Algorithmus : contains Eingabe : l ∈ ListhEi, e ∈ E Ausgabe : r ∈ {f, t} mit r = t gdw. e ∈ Inhalt(l) wenn l = Nil dann r ←f sonst wenn e = head(l) dann r ←t sonst r ← contains(tail(l), e) dasselbe kürzer: contains(l, e) ← (¬isEmpty(l))∧((head(l) = e)∨contains(tail(l), e)) 100 Einfach verkettete Liste – remove Algorithmus : remove Eingabe : l ∈ ListhEi, e ∈ E Ausgabe : r ∈ ListhEi mit Inhalt(r ) = Inhalt(l) \ {e} wenn l = Nil dann r ←l sonst wenn e = head(l) dann r ← remove(tail(l), e) sonst r ← Node(head(l), remove(tail(l), e)) Werden dabei alle Vorkommen von e aus l entfent? 101 Einfach verkettete Liste – sortiertes Einfügen für Elemente aus total geordneter Menge (E, ≤) Algorithmus : sadd Eingabe : l ∈ ListhEi, sortiert (d. h. ∀li ∈ l ∀x ∈ Inhalt(tail(li ) : head(li ) ≤ x), e∈E Ausgabe : r ∈ ListhEi sortiert mit Inhalt(r ) = Inhalt(l) ∪ {e} wenn l = Nil dann r ← Node(e, Nil) sonst wenn e > head(l) dann r ← Node(head(l), sadd(tail(l), e)) sonst r ← Node(e, l) 102 Einfach verkettete Liste – Länge (Anzahl der Speicherpositionen) Algorithmus : size Eingabe : l ∈ ListhEi Ausgabe : n ∈ N wenn l = Nil dann n←0 sonst n ← 1 + size(tail(l)) 103 Doppelt verkettete Liste Knotentyp: I I Nil (Konstante) oder Knoten aus I I I Element (head) und (Verweis auf) Liste (next) und (Verweis auf) Liste (prev) Operationen: I offensichtlich: Nil, head, prev, next, add I rekursiv: contains, remove häufiger Spezialfall: zyklische (doppelt) verkettete Liste 104 Spezielle lineare Datenstrukturen add, remove und get nur an festgelegten Positionen (remove0 ohne Element, get0 ohne Index) ADT Folge0 (Spezifikation): Sorten: Bool, E, Folge0 hEi Signatur: isEmpty : Folge0 hEi → Nil : add : Folge0 hEi × E → 0 remove : Folge0 hEi → 0 get : Folge0 hEi → Bool Folge0 hEi Folge0 hEi Folge0 hEi E Spezialfälle: Stack: andere Namen für Operationen: add 7→ push, remove’ 7→ pop, get’ 7→ top Queue: andere Namen für Operationen: add 7→ enqueue, remove’ 7→ dequeue, get’ 7→ front 105 Stack (Stapel, Keller) Idee: last in first out (LIFO) ADT Stack Sorten: Bool, Element, StackhEi Signatur: isEmpty : StackhEi → Nil : push : StackhEi × Element → pop : StackhEi → top : StackhEi → Axiome: Bool StackhEi StackhEi StackhEi Element isEmpty(Nil) = t, ∀s∀e : isEmpty(push(s, e)) = f, ∀s∀e : pop(push(s, e)) = s, ∀s∀e : top(push(s, e)) = e, . . . Realisierungen meist durch verkettete Liste oder Array 106 Queue (Warteschlange) Idee: first in first out (FIFO) ADT Queue Sorten: Bool, Element, QueuehEi Signatur: isEmpty : QueuehEi → Nil : enqueue : QueuehEi × Element → dequeue : QueuehEi → front : QueuehEi → Bool QueuehEi QueuehEi QueuehEi Element Axiome: isEmpty(Nil) = t, ∀q∀e : isEmpty(enqueue(q, e)) = f, ∀a∀b : front(enqueue(enqueue(Nil, a), b)) = a ∀a∀b : dequeue(enqueue(enqueue(Nil, a), b)) = enqueue(Nil, b), . . . Realisierung meist durch zyklisch verkettete Liste oder Array 107