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