Abstrakte Datentypen (ADT) - Otto-von-Guericke

Werbung
Einleitung
Stack
Queue
Einleitung
Stack
Queue
Gliederung
Algorithmen und Datenstrukturen – Einführung
Abstrakte Datentypen (ADT) I
1
Einleitung
2
Stack
Stacks im Alltag
ADT Stack
Implementation
3
Queue
Queues im Alltag
ADT Queue
Implementation
D. Rösner
Institut für Wissens- und Sprachverarbeitung
Fakultät für Informatik
Otto-von-Guericke Universität Magdeburg
Winter 2008/2009, 23. November 2008
D. Rösner
AuD 2008/2009 . . .
Einleitung
Stack
Queue
D. Rösner
AuD 2008/2009 . . .
Einleitung
Stack
Queue
Abstrakte Datentypen
Abstrakte Datentypen in Haskell
abstrakte Datentypen
kurz oft nur ADT genannt
sind im Unterschied zu den bisher betrachteten – konkreten
– Datentypen nicht an eine bestimmte Repräsentation
gebunden
ADTs werden implizit durch die Menge der auf ihnen
zugelassenen Operationen (Konstruktoren, Selektoren,
Prädikate) definiert
diese werden auch als das Interface des ADT bezeichnet
nur das Interface wird “Nutzern“ offengelegt
die interne Struktur – die sog. Implementierung – des ADT
bleibt “verborgen“ (Kapselung, ’information hiding’) und
könnte jederzeit geändert werden
solange das Interface unverändert bleibt, ist Code, der den
ADT nutzt, davon nicht betroffen
m.a.W.: ADTs dienen der Modularisierung
D. Rösner
AuD 2008/2009 . . .
in Haskell können ADTs durch Haskell-Module realisiert
werden
ein Modul in Haskell definiert eine Menge von Funktionen
und Datentypen in einer geschlossenen Umgebung
ein Modul kann alle oder auch nur einige ausgewählte
seiner Definitionen exportieren
definiert wird ein Modul in Haskell durch
module <name> (<exportliste>) where
<definitionen>
D. Rösner
AuD 2008/2009 . . .
Einleitung
Stack
Queue
Stacks im Alltag
ADT Stack
Implementation
ADT Stack
Einleitung
Stack
Queue
Stacks im Alltag
ADT Stack
Implementation
Stack: Alltagsbeispiele
Stack . . . dt. Stapel
im folgenden einige Beispiele aus dem Alltag
D. Rösner
AuD 2008/2009 . . .
Einleitung
Stack
Queue
Stacks im Alltag
ADT Stack
Implementation
Stack: Alltagsbeispiele
Quelle: http://www.fromoldbooks.org/pictures-of-old-books/pages/
D. Rösner
AuD 2008/2009 . . .
Einleitung
Stack
Queue
Stacks im Alltag
ADT Stack
Implementation
Stack: Alltagsbeispiele
Quelle: http://www.rotten.com/library/culture/the-simpsons/homer-pez-dispenser.jpg
D. Rösner
AuD 2008/2009 . . .
Quelle: http://www.pacificcatering.com.au/files/categories/md/
D. Rösner
AuD 2008/2009 . . .
Einleitung
Stack
Queue
Stacks im Alltag
ADT Stack
Implementation
ADT Stack
Einleitung
Stack
Queue
Stacks im Alltag
ADT Stack
Implementation
ADT Stack
abstrakter Datentyp Stack
Ein Stack ist eine homogene Sammlung von Objekten, auf
denen zwei zentrale Operationen definiert sind:
Definition
push x s
füge x als neues oberstes Element in den Stack s ein und gib
den veränderten Stack mit x als oberstem Element (sog. top)
zurück
pop s
entferne das aktuelle oberste Element vom Stack und gib den
veränderten Stack ohne x als oberstem Element als Wert
zurück; Fehler, falls Stack leer
abstrakter Datentyp Stack
Stack realisiert das LIFO-Prinzip: last-in, first-out
weitere Definitionen:
das oberste Element eines Stacks s wird durch den
Selektor top s geliefert (dieses bleibt aber auf dem Stack)
mit dem Konstruktor emptyStack wird ein leerer Stack
kreiert
das Prädikat stackEmpty prüft, ob ein Stack noch
Elemente enthält oder nicht
manchmal kann auch noch mit size die Anzahl der
Elemente auf dem Stack erfragt werden
s.a. [RL99], Ch. 5 bzw. [GT01], Ch. 4
s.a. [RL99], Ch. 5
D. Rösner
AuD 2008/2009 . . .
D. Rösner
AuD 2008/2009 . . .
Einleitung
Stack
Queue
Stacks im Alltag
ADT Stack
Implementation
Einleitung
Stack
Queue
Stacks im Alltag
ADT Stack
Implementation
ADT Stack
ADT Stack
“Stacks and queues are among the simplest of all data
structure, but are also among the most important.“ ([GT01],
p. 136)
wegen ihrer Bedeutung oft sogar in Hardware in den sog.
Mikroinstruktionen in der CPU implementiert
zentrales Element in vielen Programmierumgebungen, so
z.B. in Hugs, aber auch in der Java Virtual Machine (JVM)
s.a. [GT01], Ch. 4
Beispiele für Verwendung von Stacks:
Stack mit offenen Frames verschachtelter (rekursiver)
Aufrufe von Funktionen
sog. Operandenstack beim Auswerten arithmetischer
Ausdrücke wie ((a + b)*(c + d))/e
Speichern kürzlich besuchter WWW-Seiten in einem Stack
in einem Webbrowser
Undo-Mechanismus in Texteditoren realisiert über einen
Stack mit den Operationen zur Textänderung
s.a. [GT01], Ch. 4
D. Rösner
AuD 2008/2009 . . .
D. Rösner
AuD 2008/2009 . . .
Einleitung
Stack
Queue
Stacks im Alltag
ADT Stack
Implementation
ADT Stack
Einleitung
Stack
Queue
Stacks im Alltag
ADT Stack
Implementation
ADT Stack
Bedeutung von ’pop’ als engl. Verb (aus WordNet 2.0):
Bedeutung von ’pop’ als engl. Verb (aus WordNet 2.0) (cont.):
The verb pop has 13 senses (first 4 from tagged texts)
7. pop -- (put or thrust suddenly and forcefully; "pop the pizza
into the microwave oven"; "He popped the petit-four into his mouth")
8. pop -- (release suddenly; "pop the clutch")
9. pop -- (hit or strike; "He popped me on the head")
10. toss off, pop, bolt down, belt down, pour down, down, drink down,
kill -- (drink down entirely; "He downed three martinis before
dinner"; "She killed a bottle of brandy that night";
"They popped a few beer after work")
11. pop -- (take drugs, especially orally; "The man charged with
murder popped a valium to calm his nerves")
12. pop -- (cause to burst with a lound, explosive sound;
"The child popped the balloon")
13. pop -- (burst open with a sharp, explosive sound; "The balloon
popped"; "This popcorn pops quickly in the microwave oven")
1. (3) protrude, pop, pop out, bulge, bulge out, bug out, come out -(bulge outward; "His eyes popped")
2. (3) pop -- (hit a pop-fly; "He popped out to shortstop")
3. (1) pop -- (make a sharp explosive noise; "The cork of the
champagne bottle popped")
4. (1) pop -- (fire a weapon with a loud explosive noise;
"The soldiers were popping")
5. pop -- (cause to make a sharp explosive sound;
"He popped the champagne bottle")
6. crop up, pop up, pop -- (appear suddenly or unexpectedly;
"The farm popped into view as we turned the corner";
"He suddenly popped up out of nowhere")
D. Rösner
AuD 2008/2009 . . .
D. Rösner
AuD 2008/2009 . . .
Einleitung
Stack
Queue
Stacks im Alltag
ADT Stack
Implementation
Einleitung
Stack
Queue
Stacks im Alltag
ADT Stack
Implementation
ADT Stack
ADT Stack
die Modul-Definition (s.a. [RL99], Ch. 5):
Implementation mit einem Konstruktor
module Stack(Stack,push,pop,top,emptyStack,stackEmpty)
where
emptyStack:: Stack a
stackEmpty:: Stack a -> Bool
push :: a-> Stack a -> Stack a
pop :: Stack a -> Stack a
top :: Stack a -> a
D. Rösner
AuD 2008/2009 . . .
data Stack a = EmptyStk
| Stk a (Stack a)
emptyStack = EmptyStk
stackEmpty EmptyStk = True
stackEmpty _
= False
D. Rösner
AuD 2008/2009 . . .
Einleitung
Stack
Queue
Stacks im Alltag
ADT Stack
Implementation
ADT Stack
Einleitung
Stack
Queue
Stacks im Alltag
ADT Stack
Implementation
ADT Stack
Implementation mit einem Konstruktor (cont.)
Alternative Implementation durch Liste:
newtype Stack a = Stk [a]
push x s = Stk x s
pop EmptyStk = error "pop from an empty stack"
pop (Stk _ s) = s
top EmptyStk = error "top from an empty stack"
top (Stk x _) = x
emptyStack = Stk []
stackEmpty (Stk []) = True
stackEmpty (Stk _ ) = False
D. Rösner
AuD 2008/2009 . . .
D. Rösner
AuD 2008/2009 . . .
Einleitung
Stack
Queue
Stacks im Alltag
ADT Stack
Implementation
Einleitung
Stack
Queue
Stacks im Alltag
ADT Stack
Implementation
ADT Stack
ADT Stack
Alternative Implementation durch Liste (cont.):
eine mit deriving gewonnene show-Funktion würde die
Implementation offenlegen
push x (Stk xs) = Stk (x:xs)
daher Definition einer eigenen Darstellung für Stacks
für die Implementation mit Konstruktor:
pop (Stk [])
= error "pop from an empty stack"
pop (Stk (_:xs)) = Stk xs
Beispiel
top (Stk [])
= error "top from an empty stack"
top (Stk (x:_)) = x
instance (Show a) => Show (Stack a) where
showsPrec p EmptyStk str = showChar ’-’ str
showsPrec p (Stk x s) str = shows x (showChar ’|’ (shows s str))
D. Rösner
AuD 2008/2009 . . .
D. Rösner
AuD 2008/2009 . . .
Einleitung
Stack
Queue
Stacks im Alltag
ADT Stack
Implementation
ADT Stack
Einleitung
Stack
Queue
Queues im Alltag
ADT Queue
Implementation
ADT Queue
Definition einer eigenen Darstellung für Stacks
für die Implementation mit Liste:
Queue . . . dt. Schlange (im Sinne von Warteschlange)
Beispiel
im folgenden einige Beispiele aus dem Alltag
instance (Show a)
showsPrec p (Stk
showsPrec p (Stk
= shows x
=> Show (Stack a) where
[])
str = showChar ’-’ str
(x:xs)) str
(showChar ’|’ (shows (Stk xs) str))
D. Rösner
AuD 2008/2009 . . .
D. Rösner
AuD 2008/2009 . . .
Einleitung
Stack
Queue
Queues im Alltag
ADT Queue
Implementation
Einleitung
Stack
Queue
Queues im Alltag
ADT Queue
Implementation
Queue: Alltagsbeispiele
Quelle: http://www.istockphoto.com/
D. Rösner
Queue: Alltagsbeispiele
AuD 2008/2009 . . .
Waiting queue in front of the Science Express Quelle: www.science-express.com/.../2008/02/amit5.jpg
D. Rösner
AuD 2008/2009 . . .
Einleitung
Stack
Queue
Queues im Alltag
ADT Queue
Implementation
Einleitung
Stack
Queue
Queues im Alltag
ADT Queue
Implementation
ADT Queue
Queue: Alltagsbeispiele
abstrakter Datentyp Queue
Eine Queue ist – ähnlich wie ein Stack – eine homogene
Sammlung von Objekten, auf denen zwei zentrale
Operationen definiert sind:
Definition
enqueue x q
füge x als neues letztes Element ’hinten’ (rear) an die Queue q
an und gib die veränderte Queue zurück
dequeue q
entferne das aktuelle erste Element (front) aus der Queue und
gib die veränderte Queue als Wert zurück; Fehler, falls Queue
leer
s.a. [RL99], Ch. 5.3
Quelle: http://www.cartoonstock.com/newscartoons/cartoonists/kty/lowres/ktyn35l.jpg
D. Rösner
AuD 2008/2009 . . .
Einleitung
Stack
Queue
Queues im Alltag
ADT Queue
Implementation
ADT Queue
D. Rösner
AuD 2008/2009 . . .
Einleitung
Stack
Queue
Queues im Alltag
ADT Queue
Implementation
ADT Queue
abstrakter Datentyp Queue
Queue realisiert das FIFO-Prinzip: first-in, first-out
weitere Definitionen:
das erste Element einer Queue q wird durch den Selektor
front q geliefert (aber nicht aus der Queue entfernt)
mit dem Konstruktor emptyQueue wird eine leere Queue
kreiert
das Prädikat queueEmpty prüft, ob eine Queue noch
Elemente enthält oder nicht
manchmal kann auch noch mit size die Anzahl der
Elemente in der Queue erfragt werden
Beispiele für Verwendung von Queues:
Behörden, Läden, Theater, aber auch Mensen,
Prüfungsämer u.ä. bedienen ihre Kunden üblicherweise
nach dem FIFO-Prinzip
Queue als Datenstruktur geeignet für Verwaltung aller
Arten von Transaktionen nach diesem Prinzip
z.B. Verwaltung eingehender (telefonischer) Anfragen bei
einem Reservierungssystem oder sonstigen Call-Center
s.a. [GT01], Ch. 4.2
s.a. [RL99], Ch. 5.3 bzw. [GT01], Ch. 4.2
D. Rösner
AuD 2008/2009 . . .
D. Rösner
AuD 2008/2009 . . .
Einleitung
Stack
Queue
Queues im Alltag
ADT Queue
Implementation
ADT Queue
Queues im Alltag
ADT Queue
Implementation
ADT Queue
die Modul-Definition (s.a. [RL99], Ch. 5.3):
module Queue(Queue,emptyQueue,queueEmpty,
enqueue,dequeue,front) where
emptyQueue
queueEmpty
enqueue
dequeue
front
Einleitung
Stack
Queue
::
::
::
::
::
Queue a
Queue a ->
a -> Queue
Queue a ->
Queue a ->
Bool
a -> Queue a
Queue a
a
Implementation durch Liste:
newtype Queue a
deriving Show
emptyQueue
= Q [a]
= Q []
queueEmpty (Q [])
queueEmpty (Q _ )
= True
= False
D. Rösner
AuD 2008/2009 . . .
D. Rösner
AuD 2008/2009 . . .
Einleitung
Stack
Queue
Queues im Alltag
ADT Queue
Implementation
Einleitung
Stack
Queue
Queues im Alltag
ADT Queue
Implementation
ADT Queue
ADT Queue
Implementation durch Liste (cont.):
enqueue x (Q q)
= Q (q ++ [x])
dequeue (Q (_:xs)) = Q xs
dequeue (Q [])
= error "dequeue: empty queue"
front (Q (x:_)) = x
front (Q [])
= error "front: empty queue"
D. Rösner
AuD 2008/2009 . . .
Implementation durch Liste (cont.):
Nachteil dieser Implementation
Aufwand für enqueue ist O(n)
denn: . . .
alle anderen Operationen haben konstanten Aufwand
(O(1))
D. Rösner
AuD 2008/2009 . . .
Einleitung
Stack
Queue
Queues im Alltag
ADT Queue
Implementation
ADT Queue
Einleitung
Stack
Queue
Queues im Alltag
ADT Queue
Implementation
ADT Queue
Alternative Implementation durch ein Paar von Listen:
Idee:
erste Liste repräsentiert den Anfangsteil der Queue, zweite
den hinteren Teil in umgedrehter Ordnung
an den hinteren Teil kann dann mit konstantem Aufwand
angefügt werden
wird der Anfangsteil der Queue leer, dann wird der hintere
Teil (einmal) umgedreht und zum Anfangsteil gemacht
wird für reverse eine Implementation mit linearem
Aufwand verwendet, dann ist der durchschnittliche
Aufwand über eine Sequenz von Queue-Operationen O(1),
im schlechtesten Fall kann er aber O(n) betragen (vgl.
[RL99], Ch. 5.3)
Alternative Implementation durch ein Paar von Listen
(cont.):
newtype Queue a
= Q ([a],[a])
enqueue x (Q ([],[])) = Q ([x],[])
enqueue y (Q (xs,ys)) = Q (xs,y:ys)
dequeue (Q ([],[]))
= error "dequeue:empty queue"
dequeue (Q ([],ys))
= Q (tail(reverse ys) , [])
dequeue (Q (x:xs,ys)) = Q (xs,ys)
D. Rösner
AuD 2008/2009 . . .
D. Rösner
AuD 2008/2009 . . .
Einleitung
Stack
Queue
Queues im Alltag
ADT Queue
Implementation
Einleitung
Stack
Queue
Queues im Alltag
ADT Queue
Implementation
ADT Queue
ADT Queue
Alternative Implementation durch ein Paar von Listen
(cont.):
Alternative Implementation durch ein Paar von Listen
(cont.):
queueEmpty (Q ([],[])) = True
queueEmpty _
= False
Definition der gedruckten Darstellung in Analogie zu der
bei der Listenimplementation durch deriving
abgeleiteten
emptyQueue
= Q ([],[])
front (Q ([],[]))
= error "front:empty queue"
front (Q ([],ys))
= last ys
front (Q (x:xs,ys)) = x
D. Rösner
AuD 2008/2009 . . .
instance (Show a) => Show (Queue a) where
showsPrec p (Q (front, rear)) str
= showString "Q "
(showList (front ++ reverse rear) str)
D. Rösner
AuD 2008/2009 . . .
Einleitung
Stack
Queue
Queues im Alltag
ADT Queue
Implementation
Literatur:
Michael T. Goodrich and Roberto Tamassia.
Data Structures and Algorithms in Java.
John Wiley & Sons, New York, 2001.
ISBN 0-471-38367-8; 2nd edition.
Fethi Rabhi and Guy Lapalme.
Algorithms – A Functional Programming Approach.
Pearson Education Ltd., Essex, 1999.
2nd edition, ISBN 0-201-59604-0.
D. Rösner
AuD 2008/2009 . . .
Herunterladen