Wiederholung: Zusammenfassung Felder Algorithmen und Datenstrukturen (für ET/IT) Wintersemester / Dr. Tobias Lasser Computer Aided Medical Procedures Technische Universität München Ein Feld A kann repräsentiert werden als: sequentielle Liste (array) mit fixer Länge verkettete Liste (linked list) mit dynamischer Länge doppelt verkettete Liste (doubly linked list) mit dynamischer Länge Eigenschaften: einfach und flexibel aber manche Operationen aufwendig Als nächstes Aufgabe von Flexibilität für Effizienz Programm heute Definition Abstrakter Datentyp Einführung Mathematische Grundlagen Mengen Abbildungen Zahldarstellung Boolesche Logik Elementare Datenstrukturen Zeichenfolgen Felder Stack Queue Abstrakter Datentyp (englisch: abstract data type, ADT) Ein abstrakter Datentyp ist ein mathematisches Modell für bestimmte Datenstrukturen mit vergleichbarem Verhalten. Ein abstrakter Datentyp wird indirekt definiert über mögliche Operationen auf ihm sowie mathematische Bedingungen (oder: constraints) über die Auswirkungen der Operationen (u.u. auch die Kosten der Operationen). 4 5
Beispiel abstrakter Datentyp: abstrakte Variable Definition Stack Stack (oder deutsch: Stapel, Keller) Ein Stack ist ein abstrakter Datentyp. Er beschreibt eine spezielle Listenstruktur nach dem Last In First Out (LIFO) Prinzip mit den Eigenschaften Abstrakte Variable V ist eine vera nderliche Dateneinheit mit zwei Operationen: load(v) liefert einen Wert lo schen, einfu gen ist nur am Ende der Liste erlaubt, store(v, x) wobei x ein Wert nur das letzte Element darf manipuliert werden. und der Bedingung: Operationen auf Stacks: load(v) liefert immer den Wert x der letzten Operation push: legt ein Element auf den Stack (einfu gen) store(v, x) pop: entfernt das letzte Element vom Stack (lo schen) : liefert das letzte Stack-Element isempty: liefert true falls Stack leer initialize: Stack erzeugen und in szustand (leer) setzen 6 Definition Stack 7 Definition Stack (exakter) Stack (oder deutsch: Stapel, Keller) Stack S ist ein abstrakter Datentyp mit Operationen Ein Stack ist ein abstrakter Datentyp. Er beschreibt eine spezielle Listenstruktur nach dem Last In First Out (LIFO) Prinzip mit den Eigenschaften pop(s) liefert einen Wert push(s, x) wobei x ein Wert mit der Bedingung lo schen, einfu gen ist nur am Ende der Liste erlaubt, ist x Wert und V abstrakte Variable, dann ist die Sequenz nur das letzte Element darf manipuliert werden. push(s, x); store(v, pop(s)) a quivalent zu store(v, x) sowie der Operation "push" (S) liefert einen Wert mit der Bedingung Piz za Piz za neu e Piz Piz za za ist x Wert und V abstrakte Variable, dann ist die Sequenz # push(s, x); store(v, (S)); a quivalent zu push(s, x); store(v, x) # # 8 9
Definition Stack (exakter, Teil ) Anwendungsbeispiele Stack Stack S. Weitere Operationen sind isempty(s) liefert true oder false initialize() liefert eine Stack Instanz mit den Bedingungen initialize() S für jeden Stack S (d.h. jeder neue Stack ist separat von alten Stacks) isempty(initialize()) == true (d.h. ein neuer Stack ist leer) isempty(push(s, x)) == false (d.h. ein Stack nach push ist nicht leer) Call-Stack bei Funktionsaufrufen (s. Übung vom 9..) Auswertung arithmetischer Ausdrücke (s. nächste Folie) Einfache Vorwärts- / Rückwärts Funktion in Software z.b. im Internet-Browser Syntaxanalyse eines Programms z.b. zur Erkennung von Syntax-Fehlern durch Compiler Auswertung arithmetischer Ausdrücke Implementation Stack Gegeben sei ein vollständig geklammerter, einfacher arithmetischer Ausdruck mit Bestandteilen Zahl, +, *, = Beispiel: ( * (4 + 5)) = Schema: arbeite Ausdruck von links nach rechts ab, speichere jedes Zeichen ausser ) und = in Stack S bei ) werte die obersten Elemente von S aus, dann entferne die passende Klammer ( bei = steht das Ergebnis im obersten Stack-Element von S Stack ist abstrakter Datentyp. Implementation ist nicht festgelegt nur Operationen und Bedingungen sind festgelegt Stack kann auf viele Arten implementiert werden, zum Beispiel als: sequentielle Liste verkettete Liste 4
Implementation Stack als sequentielle Liste Implementation Stack als sequentielle Liste Stack-Elemente speichern in sequentieller Liste A oberstes Stack-Element merken mittels Variable n- n-... - initialize(); falls Stack leer ist == - n- n-... - n- n-... 9 4 - push(); push(4); push(9); push(x) inkrementiert und speichert x in A[] n- n-... 9 4 - pop(); pop() liefert A[] zurück und dekrementiert () liefert A[] zurück 5 6 Code-Beispiel: Stack als sequentielle Liste Implementation Stack als verkettete Liste int stack []; // fixe Groesse! int ; void initialize () { = -; } void push ( int x) { ++ ; // keine Fehlererkennung falls zu gross! stack [ ] = x; } int pop () { int wert = stack [ ]; -- ; // keine Fehlererkennung falls Stack leer! return wert ; } Stack-Elemente speichern in verketteter Liste L oberstes Stack-Element wird durch start Zeiger markiert start Daten Daten Daten Daten next next next next push(x) fügt Element an erster Position ein NULL pop() liefert Element an erster Position zurück und entfernt es () liefert Element an erster Position zurück 7 8
Stacks in C++ Zusammenfassung Stack in der C++ Standard Library: std::stack<datatype> unterstützte Operationen: push pop (liefer aber nichts zurück!) empty implementiert wahlweise als doppelt verkettete Liste als std::stack<datatype, std::list<datatype> > sequentielle Liste als std::stack<datatype, std::vector<datatype> > std::dequeue (default, zerstückelte sequentielle Liste) Stack ist abstrakter Datentyp als Metapher für einen Stapel wesentliche Operationen: push, pop Implementation als sequentielle Liste fixe Größe (entweder Speicher verschwendet oder zu klein) push, pop sehr effizient Implementation als verkettete Liste dynamische Größe, aber Platz für Zeiger verschwendet push, pop sehr effizient 9 Programm heute Einführung Mathematische Grundlagen Mengen Abbildungen Zahldarstellung Boolesche Logik Definition Queue Queue (oder deutsch: Warteschlange) Eine Queue ist ein abstrakter Datentyp. Sie beschreibt eine spezielle Listenstruktur nach dem First In First Out (FIFO) Prinzip mit den Eigenschaften einfügen ist nur am Ende der Liste erlaubt, entfernen ist nur am der Liste erlaubt. Elementare Datenstrukturen Zeichenfolgen Felder Stack Queue Person verlässt Schlange Person stellt sich an
Definition Queue Queue (oder deutsch: Warteschlange) Eine Queue ist ein abstrakter Datentyp. Sie beschreibt eine spezielle Listenstruktur nach dem First In First Out (FIFO) Prinzip mit den Eigenschaften einfügen ist nur am Ende der Liste erlaubt, entfernen ist nur am der Liste erlaubt. Operationen auf Queues: enqueue: fügt ein Element am Ende der Schlange hinzu dequeue: entfernt das erste Element der Schlange isempty: liefert true falls Queue leer initialize: Queue erzeugen und in szustand (leer) setzen Definition Queue (exakter) Queue Q ist ein abstrakter Datentyp mit Operationen dequeue(q) liefert einen Wert enqueue(q, x) wobei x ein Wert isempty(q) liefert true oder false initialize liefert eine Queue Instanz und mit Bedingungen ist x Wert, V abstrakte Variable und Q eine leere Queue, dann ist die Sequenz enqueue(q, x); store(v, dequeue(q)) äquivalent zu store(v, x) sind x,y Werte, V abstrakte Variable und Q eine leere Queue, dann ist die Sequenz enqueue(q, x); enqueue(q, y); store(v, dequeue(q)) äquivalent zu store(v, x); enqueue(q, y) initialize() Q für jede Queue Q isempty(initialize()) == true isempty(enqueue(q, x)) == false 4 Beispiel: Queue Anwendungsbeispiele Queue Q = initialize(); enqueue(); Druckerwarteschlange enqueue(); Playlist von itunes (oder ähnlichem Musikprogramm) Kundenaufträge bei Webshops enqueue(); Warteschlange für Prozesse im Betriebssystem (Multitasking) dequeue(); dequeue(); 5 6
Anwendungsbeispiel Stack und Queue Palindrom Erkennung Palindrom Ein Palindrom ist eine Zeichenkette, die von vorn und von hinten gelesen gleich bleibt. Beispiel: Reittier Erkennung ob Zeichenkette ein Palindrom ist ein Stack kann die Reihenfolge der Zeichen umkehren eine Queue behält die Reihenfolge der Zeichen Algorithmus: Eingabe: Zeichenkette k durchlaufe k von links nach rechts füge dabei jedes Zeichen in Stack S (push) und Queue Q (enqueue) ein leere den Stack S (pop) und die Queue Q (dequeue) und vergleiche die Zeichen falls die Zeichen nicht gleich sind, ist k kein Palindrom ansonsten ist k Palindrom Ausgabe: k ist Palindrom oder nicht Zeichenkette k: RADAR Queue Stack S: R A D A R R A D A R 7 8 Implementation Queue Implementation Queue als verkettete Liste Auch Queue ist abstrakter Datentyp. Implementation ist nicht festgelegt nur Operationen und Bedingungen sind festgelegt Queue kann auf viele Arten implementiert werden, zum Beispiel als: verkettete Liste sequentielle Liste Queue-Elemente speichern in verketteter Liste L der Queue wird durch anfang Zeiger markiert Ende der Queue wird durch extra ende Zeiger markiert anfang Daten Daten Daten Daten next next next next enqueue(x) fügt Element bei ende Zeiger ein NULL dequeue() liefert Element bei anfang Zeiger zurück und entfernt es ende 9
Implementation Queue als sequentielle Liste Implementation Queue als sequentielle Liste Queue-Element speichern in sequentieller Liste L der Queue wird durch Index anfang markiert Ende der Queue wird durch Index ende markiert Problem: n- n-... 5 8 ende anfang n- n-... 5 8 wird nach ein paar Operationen zu n- n-... 47 ende anfang ende anfang enqueue(x) fügt Element bei Index ende+ ein dequeue liefert Element bei Index anfang zurück und entfernt es durch Inkrement von anfang Linksdrift! Lösungsansatz: zirkuläre sequentielle Liste. Implementation Queue als zwei Stacks Queue Q kann mittels zwei Stacks implementiert werden erster Stack inbox wird für enqueue benutzt: Q.enqueue(x) resultiert in inbox.push(x) zweiter Stack outbox wird für dequeue benutzt: falls outbox leer, kopiere alle Elemente von inbox zu outbox: outbox.push( inbox.pop() ) enqueue Q.dequeue liefert outbox.pop() zurück dequeue Queues in C++ in der C++ Standard Library: std::queue<datatype> unterstützte Operationen: push (= enqueue) pop (= dequeue, liefert aber nichts zurück!) front back empty implementiert wahlweise als doppelt verkettete Liste als std::queue<datatype, std::list<datatype > std::dequeue (default, zerstückelte sequentielle Liste) inbox outbox inbox outbox 4
Zusammenfassung Queue Zusammenfassung Queue ist abstrakter Datentyp als Metapher für eine Warteschlange wesentliche Operationen: enqueue, dequeue Implementation als verkettete Liste dynamische Größe, aber Platz für Zeiger verschwendet enqueue, dequeue sehr effizient Implementation als sequentielle Liste fixe Größe (entweder Speicher verschwendet oder zu klein) enqueue, dequeue sehr effizient Queue sehr schnell voll durch Linksdrift (ist aber durch zirkuläre sequentielle Liste lösbar) Einführung Mathematische Grundlagen Mengen Abbildungen Zahldarstellung Boolesche Logik Elementare Datenstrukturen Zeichenfolgen Felder Stack Queue 5 6