1 / 31

Gliederung

Gliederung. Motivation / Grundlagen Sortierverfahren Elementare Datenstrukturen / Anwendungen Bäume / Graphen Hashing Algorithmische Geometrie. Einleitung. „unser“ Blick auf Datenstrukturen. ... werden charakterisiert durch. Menge der zu verwaltenden Objekte

heller
Download Presentation

Gliederung

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Gliederung • Motivation / Grundlagen • Sortierverfahren • Elementare Datenstrukturen / Anwendungen • Bäume / Graphen • Hashing • Algorithmische Geometrie

  2. Einleitung • „unser“ Blick auf Datenstrukturen ... werden charakterisiert durch • Menge der zu verwaltenden Objekte • Menge der zu unterstützenden Operationen • einfache Beispiele • Warteschlangen (/* Queues */) • Kellerspeicher (/* Stacks */) • Prioritätswarteschlangen (/* Priority Queues */)

  3. Warteschlangen / Kellerspeicher • Aufgabenstellung • Menge von zu verwaltenden Objekten • Objekte können hinzugefügt bzw. entfernt werden • zeitliche Reihenfolge des Einfügens ist entscheidend FIFO-Prinzip ... (/* first in, first out */)  Warteschlange LIFO-Prinzip ... (/* last in, first out */)  Kellerspeicher • Implementierungsvarianten • Array von Objekten • verkettete Liste von Objekten

  4. Warteschlangen / Kellerspeicher • Operationen • Erzeugen einer leeren Warteschlange bzw. eines leeren Kellerspeichers • (/* create(Q) bzw. create(S) */) • Einfügen eines Objekts o in eine Warteschlange Q bzw. einen Kellerspeicher S (/* insert(Q,o) bzw. insert(S,o) */) • Test, ob eine Warteschlange Q bzw. ein Kellerspeicher S leer ist(/* empty?(Q) bzw. empty?(S) */) • Zugriff auf das zuerst in die Warteschlange Q bzw. das zuletzt in den Kellerspeicher S eingefügte Objekt (/* access(Q) bzw. access(S) */) • Entfernen des zuerst in die Warteschlange Q bzw. des zuletzt in den Kellerspeicher S eingefügte Objekt (/* delete(Q) bzw. delete(S) */)

  5. Warteschlangen / Kellerspeicher • Beschreibung der Operationen • mindestens zwei Möglichkeiten • Möglichkeit 1 (/* implementierungsabhängig */) • festlegen, wie die Objekte intern verwaltet werden (/* etwa mit Hilfe eines Arrays oder einer verketteten Liste */) • „ausprogrammieren“ der Operationen • Möglichkeit 2 (/* implementierungsunabhängig */) • gewünschte Eigenschaften der Operationen formal beschreiben; de facto wird das „Zusammenspiel“ zwischen den Operationen festgelegt offen: Welche Beschreibungsmittel verwendet man hier?

  6. Warteschlangen / Kellerspeicher • Randbedingungen (/* implementierungsabhängig */) • die zu verwaltenden Objekte werden in einem Array gespeichert (/* damit ist klar, daß die Anzahl der zu verwaltenden Objekte a priori beschränkt ist */) • über die Indizes kann man auf die aktuell verwalteten Objekte zugreifen • die Anzahl der verwalteten Objekte ist von Relevanz (/* wird sich „gemerkt“, um die Operationen einfacher zu realisieren */)

  7. Warteschlangen • Realisierung 1 (/* ungeschickt */) • Array queue zum Verwalten von maximal n Objekten • Variable anz, um sich die Anzahl der verwalteten Objekte zu merken • create(Q): Anlegen eines Arrays queue der Größe n; anz = 0 • empty?(Q): if ( anz == 0 ) return(true) else return(false) • insert(Q,o): ++anz; queue[anz] = o • access(Q): return(queue[1]) • delete(Q): for ( i = 1; i <= anz; ++i ) { queue[i] = queue[i+1]; }; • --anz ... insert(), access() und delete() bedürfen noch eines Tests auf Anwendbarkeit

  8. Warteschlangen • Realisierung 1 (/* ungeschickt */) • Operation delete() benötigt die Zeit O(n) • alle anderen Operationen benötigen die Zeit O(1) • Verbesserungsmöglichkeit, um alle Operationen in Zeit O(1) zu realisieren: • der Index des zuerst gespeicherten Objekts ändert sich (/* muß sich aber explizit „gemerkt“ werden */) (/* Realisierung 1 */) (/* Realisierung 2 */)

  9. Warteschlangen • Realisierung 2 (/* geschickter */) • Array queue zum Verwalten von maximal n Objekten • Variable anz, um sich die Anzahl der verwalteten Objekte zu merken • Variable first, um sich den Index des zu erst eingefügten Objekts zu merken • create(Q): ...; anz = 0; first = 1 • insert(Q,o): ++anz; z = first+anz-1; • if ( z <= n ) queue[z] = o else queue[z-n] = o • delete(Q): if ( first == n) first = 1 else ++first ... insert(), access() und delete() bedürfen noch eines Tests auf Anwendbarkeit

  10. Warteschlangen • Beschreibung (/* implementierungsunabhängig */) • gewünschte Eigenschaften der Operationen formal beschreiben; de facto wird das „Zusammenspiel“ zwischen den Operationen festgelegt ... wählen bedingte Gleichungen (/* Theorie der Abstrakte Datentypen */) empty?(create(Q)) = true empty?(insert(Q,o)) = false empty?(Q) = true  access(insert(Q,o)) = o empty?(Q) = false  access(insert(Q,o)) = access(Q) empty?(Q) = false  delete(insert(Q,o)) = insert(delete(Q),o) empty?(Q) = true  delete(insert(Q,o)) = Q

  11. Kellerspeicher • Realisierung • Array stack zum Verwalten von maximal n Objekten • Variable anz, um sich die Anzahl der verwalteten Objekte zu merken • create(S): Anlegen eines Arrays stack der Größe n; anz = 0 • empty?(S): if ( anz = 0 ) return(true) else return(false) • insert(S,o): ++anz; stack[anz] = o • access(S): return(stack[anz]) • delete(S): --anz ... insert(), access() und delete() bedürfen noch eines Tests auf Anwendbarkeit

  12. Kellerspeicher • Realisierung • alle Operationen benötigen die Zeit O(1)

  13. Kellerspeicher • Beschreibung (/* implementierungsunabhängig */) • gewünschte Eigenschaften der Operationen formal beschreiben; de facto wird das „Zusammenspiel“ zwischen den Operationen festgelegt ... wählen bedingte Gleichungen (/* Theorie der Abstrakte Datentypen */) empty?(create(S)) = true empty?(insert(S,o)) = false access(insert(S,o)) = o delete(insert(S,o)) = S

  14. Anwendungen von Kellerspeichern Stacks • Beispiele • Realisierung rekursiver Funktionen • Auswertung arithmetischer Ausdrücke • Auswertung arithmetischer Ausdrücke (/* Randbedingungen */) • nur binäre Operationen • vollständig geklammerte Ausdrücke

  15. Auswertung arithmetischer Ausdrücke Stacks • Grundlagen (/* Infix- versus Postfix-Notation */) Postfix-Notation Infix-Notation xy+ xy+z* xxy+*z+ (x+y) ((x*y)+z) ((x*(x+y))+z) Klammern in der Infix-Notation dienen zur „Repräsentation“ von Prioritätenvon Operatoren (/* hier machen wir uns das Leben „einfacher“ */)

  16. Auswertung arithmetischer Ausdrücke Stacks • Auswertung eines arithmetischen Ausdrucks in Infix-Notation + ((x*(x+y))+z) * val(z) val(x) + val(x) val(y) ... Auswertung gemäß Baumstruktur (/* aufbauen + auswerten */)

  17. Auswertung arithmetischer Ausdrücke Stacks • Aufgabenstellung • gegeben ein vollständig geklammerter arithmetischer Ausdruck in Infix-Notation (/* falls nicht, so müssen die Klammern gemäß der Prioritäten der Operatoren eingefügt werden */) • gesucht ist der Wert des Ausdrucks (/* ... die Werte der auftretenden Variablen sind bekannt */) • Herangehensweise • Schritt 1: Umwandlung von Infix-Notation in Postfix-Notation • Schritt 2: Auswertung des Ausdrucks in Postfix-Notation

  18. Auswertung arithmetischer Ausdrücke Stacks • Auswertung eines arithmetischen Ausdrucks in Postfix-Notation von links nach rechts durchlaufen; unter Verwendung eines Stacks auswerten Ausgabe: 11 Auszuwertender Ausdruck: ((2*(2+3))+1)

  19. Auswertung arithmetischer Ausdrücke Stacks • Auswertung eines arithmetischen Ausdrucks in Postfix-Notation von links nach rechts durchlaufen; unter Verwendung eines Stacks auswerten Abkürzungen: a = val(x) b = val(y) e = val(z) f = d+e Ausgabe: f c = a+b d = a+c Auszuwertender Ausdruck: ((x*(x+y))+z)

  20. Auswertung arithmetischer Ausdrücke Stacks • Regeln für Schritt 2 • führe create(S) aus • arithmetischen Ausdruck von links nach rechts durchlaufen • falls das aktuelle Zeichen z ein Operand ist, so führe insert(S,val(z)) aus • falls das aktuelles Zeichen z ein Operator ist, so bestimme a = access(S), führe delete(S) aus, bestimme b = access(S), führe delete(S) aus, berechne c = z(a,b) und führe insert(S,c) aus • falls der Ausdruck vollständig gelesen wurde, so gib access(S) aus

  21. Auswertung arithmetischer Ausdrücke Stacks • Umwandlung von Infix-Notation in Postfix-Notation von links nach rechts durchlaufen; unter Verwendung eines Stacks ausgeben Ausgabe:

  22. Auswertung arithmetischer Ausdrücke Stacks • Regeln für Schritt 2 • führe create(S) aus • arithmetischen Ausdruck von links nach rechts durchlaufen • falls das aktuelle Zeichen z das Zeichen “(“ ist, so ignoriere z • falls das aktuelle Zeichen z ein Operand ist, so gebe z aus • falls das aktuelle Zeichen z ein Operator ist, so führe insert(S,z) aus • falls das aktuelles Zeichen z das Zeichen “)“ ist, so bestimme y = access(S), gib y aus und führe delete(S) aus

  23. Prioritätswarteschlangen Stacks • Aufgabenstellung • Menge von zu verwaltenden Objekten, wobei jedem Objekt eine „Priorität“ zugeordnet ist • Objekte können hinzugefügt bzw. entfernt werden • in der verwalteten Menge will man schnell ein Objekt mit der höchsten Priorität bestimmen können ... betrachten Varianten der Realisierung mit Hilfe eines Arrays, d.h. die Anzahl der zu verwaltenden Objekte ist a priori begrenzt

  24. Prioritätswarteschlangen Stacks • Operationen • Erzeugen einer leeren Prioritätswarteschlange P • (/* create(P) */) • Einfügen eines Objekts o in eine Prioritätswarteschlange P(/* insert(P,o) */) • Zugriff auf ein Objekt in der Prioritätswarteschlange P mit minimaler Priorität, wobei dieses Objekt gleichzeitig aus P gestrichen werden soll (/* acc_del(P) */) • Erzeugen einer Prioritätswarteschlange P, die alle Objekte einer Objektmenge O enthält (/* init(P,O) */)

  25. Prioritätswarteschlangen Stacks • Anwendungen • Steuerung von Druckerwarteschlangen (/* den Benutzern werden Gruppen zugeordnet, ... */) • als zugrunde liegende Datenstruktur diverser Algorithmen (/* sehen wir später */)

  26. Prioritätswarteschlangen Stacks • Realisierung 1 (/* ungeschickt */) • Array pqueue zum Verwalten von maximal n Objekten • Variable anz, um sich die Anzahl der verwalteten Objekte zu merken • create(P): Anlegen eines Arrays pqueue der Größe n; anz = 0 • insert(P,o): ++anz; pqueue[anz] = o • acc_del(P): bestimme i mit p(pqueue[i]) ist maximal; • return(queue[1]); • for ( j = i; j < anz; ++j ) { pqueue[j] = pqueue[j+1]; }; • --anz • init(P,O): führe erst create(P) und dann „nacheinander“ für • jedes Objekt o  O die Operation insert(P,o) aus ... insert(), acc_del() und init() bedürfen noch eines Tests auf Anwendbarkeit

  27. Prioritätswarteschlangen Stacks • Realisierung 1 (/* ungeschickt */) • Operationen create(P) und insert(P,o) gehen in Zeit O(1) • Operationen acc_del(P) und init(P,O) benötigen Zeit O(n) • Verbesserungsmöglichkeit • Array pqueue zum Verwalten von maximal n Objekten • Variable anz, um sich die Anzahl der verwalteten Objekte zu merken • das Array pqueue, in dem die Objekte verwaltet werden, bildet einen Heap (/* Ordnung der Objekte bzgl. der zugehörigen Prioritäten */)

  28. Prioritätswarteschlangen Stacks • Beispiel • O = { a,b,c,d,e,f,g } • p(a) = p(g) = 5, p(b) = 1, p(c) = p(e) = p(f) = 3, p(d) = 2 a e g d b f c Ein Knoten o mit den Söhnen ol und or hat die Heap-Eigenschaft, falls p(o) ≥ p(ol) und p(o) ≥ p(or) gilt. ... jeder Knoten muß die Heap- Eigenschaft haben

  29. Prioritätswarteschlangen • insert()-Operation ... geht in Zeit O(log(n)) • ++anz; pqueue[anz] = o • auf dem Weg von pqueue[1] zu pqueue[anz] das neue Objekt o an die richtige Position „steigen“ lassen • O = { a,b,c,d,e,f,g } • p(a) = p(g) = 5, p(b) = 1, p(c) = p(e) = p(f) = 3, p(d) = 6 d a a g a g f g f c e b f c e b d c e b

  30. Prioritätswarteschlangen • acc_del()-Operation ... geht in Zeit O(log(n)) • y = pqueue[1]; pqueue[1] = pqueue[anz]; --anz • Objekt an Position pqueue[1] an die richtige Position „sinken“ lassen; return(y) • O = { a,b,c,d,e,f,g } • p(a) = p(g) = 5, p(b) = 1, p(c) = p(e) = p(f) = 3, p(d) = 2 a g c e g e c e g d b d b f c d b f f

  31. Prioritätswarteschlangen • init()-Operation ... geht in Zeit O(n) • Array pqueue mit allen Objekten in O initialisieren (/* ohne die Ordnung bzgl. der Prioritäten zu beachten */) • Array pqueue wie in Phase 1 von HeapSort in einen Heap überführen (/* Ordnung absteigend bzgl. der Prioritäten */) • O = { a,b,c,d,e,f,g } • p(a) = p(g) = 5, p(b) = 1, p(c) = p(e) = p(f) = 3, p(d) = 6 d a a g b c b e f c d e f g

More Related