Algorithmen und Datenstrukturen I

Werbung
Einleitung
Stack
Queue
Einleitung
Stack
Queue
Gliederung
Algorithmen und Datenstrukturen I
Abstrakte Datentypen
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
c
Winter 2009/10, 22. November 2009, 2009/10
D.Rösner
D. Rösner AuD I 2009/10 . . .
1
Einleitung
Stack
Queue
D. Rösner AuD I 2009/10 . . .
2
Einleitung
Stack
Queue
Abstrakte Datentypen
Abstrakte Datentypen
abstrakte Datentypen
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 definiert durch die Menge der auf
ihnen zugelassenen Operationen:
...
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
Konstruktoren,
Selektoren,
Prädikate
diese werden auch als das Interface des ADT bezeichnet
...
D. Rösner AuD I 2009/10 . . .
3
D. Rösner AuD I 2009/10 . . .
4
Einleitung
Stack
Queue
Einleitung
Stack
Queue
Abstrakte Datentypen in Haskell
Stacks im Alltag
ADT Stack
Implementation
ADT Stack
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
Stack . . . dt. Stapel
im folgenden einige Beispiele aus dem Alltag
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 I 2009/10 . . .
Einleitung
Stack
Queue
5
Stacks im Alltag
ADT Stack
Implementation
D. Rösner AuD I 2009/10 . . .
Einleitung
Stack
Queue
Stack: Alltagsbeispiele
7
Stacks im Alltag
ADT Stack
Implementation
Stack: Alltagsbeispiele
Quelle: http://www.rotten.com/library/culture/the-simpsons/homer-pez-dispenser.jpg
Quelle: http://www.fromoldbooks.org/pictures-of-old-books/pages/
D. Rösner AuD I 2009/10 . . .
8
D. Rösner AuD I 2009/10 . . .
9
Einleitung
Stack
Queue
Stacks im Alltag
ADT Stack
Implementation
Einleitung
Stack
Queue
Stack: Alltagsbeispiele
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
s.a. [RL99], Ch. 5
Quelle: http://www.pacificcatering.com.au/files/categories/md/
D. Rösner AuD I 2009/10 . . .
Einleitung
Stack
Queue
10
D. Rösner AuD I 2009/10 . . .
Stacks im Alltag
ADT Stack
Implementation
Einleitung
Stack
Queue
ADT Stack
12
Stacks im Alltag
ADT Stack
Implementation
ADT Stack
abstrakter Datentyp Stack
Stack realisiert das LIFO-Prinzip: last-in, first-out
weitere Definitionen:
“Stacks and queues are among the simplest of all data
structure, but are also among the most important.“ ([GT01],
p. 136)
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
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)
manchmal kann auch noch mit size die Anzahl der
Elemente auf dem Stack erfragt werden
s.a. [GT01], Ch. 4
s.a. [RL99], Ch. 5 bzw. [GT01], Ch. 4
D. Rösner AuD I 2009/10 . . .
13
D. Rösner AuD I 2009/10 . . .
14
Einleitung
Stack
Queue
Stacks im Alltag
ADT Stack
Implementation
Einleitung
Stack
Queue
ADT Stack
Stacks im Alltag
ADT Stack
Implementation
ADT Stack
Bedeutung von ’pop’ als engl. Verb (aus WordNet 2.0):
Beispiele für Verwendung von Stacks:
The verb pop has 13 senses (first 4 from tagged texts)
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
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")
s.a. [GT01], Ch. 4
D. Rösner AuD I 2009/10 . . .
Einleitung
Stack
Queue
15
D. Rösner AuD I 2009/10 . . .
Stacks im Alltag
ADT Stack
Implementation
Einleitung
Stack
Queue
ADT Stack
16
Stacks im Alltag
ADT Stack
Implementation
ADT Stack
Bedeutung von ’pop’ als engl. Verb (aus WordNet 2.0) (cont.):
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")
D. Rösner AuD I 2009/10 . . .
17
die Modul-Definition (s.a. [RL99], Ch. 5):
module Stack(Stack,push,pop,top,emptyStack,stackEmpty)
where
emptyStack::
stackEmpty::
push :: a ->
pop :: Stack
top :: Stack
Stack a
Stack a -> Bool
Stack a -> Stack a
a -> Stack a
a -> a
D. Rösner AuD I 2009/10 . . .
19
Einleitung
Stack
Queue
Stacks im Alltag
ADT Stack
Implementation
Einleitung
Stack
Queue
ADT Stack
Stacks im Alltag
ADT Stack
Implementation
ADT Stack
Implementation mit einem Konstruktor
Implementation mit einem Konstruktor (cont.)
data Stack a = EmptyStk
| Stk a (Stack a)
push x s = Stk x s
emptyStack = EmptyStk
pop EmptyStk = error "pop from an empty stack"
pop (Stk _ s) = s
stackEmpty EmptyStk = True
stackEmpty _
= False
D. Rösner AuD I 2009/10 . . .
Einleitung
Stack
Queue
top EmptyStk = error "top from an empty stack"
top (Stk x _) = x
20
D. Rösner AuD I 2009/10 . . .
Stacks im Alltag
ADT Stack
Implementation
Einleitung
Stack
Queue
ADT Stack
21
Stacks im Alltag
ADT Stack
Implementation
ADT Stack
Alternative Implementation durch Liste (cont.):
Alternative Implementation durch Liste:
newtype Stack a = Stk [a]
push x (Stk xs) = Stk (x:xs)
emptyStack = Stk []
pop (Stk [])
= error "pop from an empty stack"
pop (Stk (_:xs)) = Stk xs
stackEmpty (Stk []) = True
stackEmpty (Stk _ ) = False
D. Rösner AuD I 2009/10 . . .
top (Stk [])
= error "top from an empty stack"
top (Stk (x:_)) = x
22
D. Rösner AuD I 2009/10 . . .
23
Einleitung
Stack
Queue
Stacks im Alltag
ADT Stack
Implementation
Einleitung
Stack
Queue
ADT Stack
Stacks im Alltag
ADT Stack
Implementation
ADT Stack
eine mit deriving gewonnene show-Funktion würde die
Implementation offenlegen
Definition einer eigenen Darstellung für Stacks
daher Definition einer eigenen Darstellung für Stacks
für die Implementation mit Liste:
Beispiel
für die Implementation mit Konstruktor:
instance (Show a)
showsPrec p (Stk
showsPrec p (Stk
= shows x
Beispiel
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 I 2009/10 . . .
Einleitung
Stack
Queue
=> Show (Stack a) where
[])
str = showChar ’-’ str
(x:xs)) str
(showChar ’|’ (shows (Stk xs) str))
24
D. Rösner AuD I 2009/10 . . .
Queues im Alltag
ADT Queue
Implementation
Einleitung
Stack
Queue
ADT Queue
25
Queues im Alltag
ADT Queue
Implementation
Queue: Alltagsbeispiele
Queue . . . dt. Schlange (im Sinne von Warteschlange)
im folgenden einige Beispiele aus dem Alltag
D. Rösner AuD I 2009/10 . . .
27
Quelle: http://www.istockphoto.com/
D. Rösner AuD I 2009/10 . . .
28
Einleitung
Stack
Queue
Queues im Alltag
ADT Queue
Implementation
Einleitung
Stack
Queue
Queue: Alltagsbeispiele
Queue: Alltagsbeispiele
Waiting queue in front of the Science Express Quelle: www.science-express.com/.../2008/02/amit5.jpg
D. Rösner AuD I 2009/10 . . .
Einleitung
Stack
Queue
Queues im Alltag
ADT Queue
Implementation
29
Quelle: http://www.cartoonstock.com/newscartoons/cartoonists/kty/lowres/ktyn35l.jpg
D. Rösner AuD I 2009/10 . . .
Queues im Alltag
ADT Queue
Implementation
Einleitung
Stack
Queue
ADT Queue
30
Queues im Alltag
ADT Queue
Implementation
ADT Queue
abstrakter Datentyp Queue
Eine Queue ist – ähnlich wie ein Stack – eine homogene
Sammlung von Objekten, auf denen zwei zentrale
Operationen definiert sind:
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
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
manchmal kann auch noch mit size die Anzahl der
Elemente in der Queue erfragt werden
s.a. [RL99], Ch. 5.3 bzw. [GT01], Ch. 4.2
s.a. [RL99], Ch. 5.3
D. Rösner AuD I 2009/10 . . .
32
D. Rösner AuD I 2009/10 . . .
33
Einleitung
Stack
Queue
Queues im Alltag
ADT Queue
Implementation
Einleitung
Stack
Queue
ADT Queue
Queues im Alltag
ADT Queue
Implementation
ADT Queue
die Modul-Definition (s.a. [RL99], Ch. 5.3):
Beispiele für Verwendung von Queues:
module Queue(Queue,emptyQueue,queueEmpty,
enqueue,dequeue,front) where
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
D. Rösner AuD I 2009/10 . . .
Einleitung
Stack
Queue
emptyQueue
queueEmpty
enqueue
dequeue
front
::
::
::
::
::
Queue a
Queue a ->
a -> Queue
Queue a ->
Queue a ->
34
D. Rösner AuD I 2009/10 . . .
Queues im Alltag
ADT Queue
Implementation
Einleitung
Stack
Queue
ADT Queue
Bool
a -> Queue a
Queue a
a
Queues im Alltag
ADT Queue
Implementation
ADT Queue
Implementation durch Liste:
Implementation durch Liste (cont.):
newtype Queue a
deriving Show
enqueue x (Q q)
emptyQueue
36
= Q [a]
dequeue (Q (_:xs)) = Q xs
dequeue (Q [])
= error "dequeue: empty queue"
= Q []
queueEmpty (Q [])
queueEmpty (Q _ )
= True
= False
D. Rösner AuD I 2009/10 . . .
= Q (q ++ [x])
front (Q (x:_)) = x
front (Q [])
= error "front: empty queue"
37
D. Rösner AuD I 2009/10 . . .
38
Einleitung
Stack
Queue
Queues im Alltag
ADT Queue
Implementation
Einleitung
Stack
Queue
ADT Queue
Queues im Alltag
ADT Queue
Implementation
ADT Queue
Implementation durch Liste (cont.):
Nachteil dieser Implementation
Alternative Implementation durch ein Paar von Listen:
Idee:
Aufwand für enqueue ist O(n)
denn:
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
................................
................................
...
alle anderen Operationen haben konstanten Aufwand
(O(1))
D. Rösner AuD I 2009/10 . . .
Einleitung
Stack
Queue
39
D. Rösner AuD I 2009/10 . . .
Queues im Alltag
ADT Queue
Implementation
Einleitung
Stack
Queue
ADT Queue
40
Queues im Alltag
ADT Queue
Implementation
ADT Queue
Alternative Implementation durch ein Paar von Listen
(cont.):
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)
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 I 2009/10 . . .
41
D. Rösner AuD I 2009/10 . . .
42
Einleitung
Stack
Queue
Queues im Alltag
ADT Queue
Implementation
Einleitung
Stack
Queue
ADT Queue
Queues im Alltag
ADT Queue
Implementation
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 ([],[])
instance (Show a) => Show (Queue a) where
showsPrec p (Q (front, rear)) str
= showString "Q "
(showList (front ++ reverse rear) str)
front (Q ([],[]))
= error "front:empty queue"
front (Q ([],ys))
= last ys
front (Q (x:xs,ys)) = x
D. Rösner AuD I 2009/10 . . .
Einleitung
Stack
Queue
43
Queues im Alltag
ADT Queue
Implementation
Literatur: I
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 I 2009/10 . . .
45
D. Rösner AuD I 2009/10 . . .
44
Herunterladen