Algorithmen und Datenstrukturen

Werbung
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
Herunterladen