Was bisher geschah ADT Menge Operationen: I Suche nach einem Element I Einfügen eines Elementes I Löschen eines Elementes Datenstrukturen für ADT Menge I lineare Datenstrukturen: Array, Liste, Hashtabelle I hierarchische Datenstrukturen: Suchbäume, balancierte Suchbäume 178 Priority-Queues (Vorrang-Warteschlange) Idee: I Modellierung von Prioritäten, z.B. Dringlichkeit I Datenstruktur zur Verwaltung von Paaren (Element, Schlüssel) I Schlüssel repräsentieren Priorität I oft Rangfolge: kleiner Schlüssel = hohe Priorität I Zugriff nur auf ein Element mit minimalem Schlüssel (maximale Priorität) 179 ADT Priority-Queue Priority-Queue: Menge von Schlüsseln (Prioritäten) aus einer Menge mit Ordnung I I Sorten: Bool, Element, PQ (kurz für PQhElementi) Signatur: isEmpty : PQ → emptyPQ : add : PQ × Element → deletemin : PQ → I Bool PQ PQ Element × PQ Modell: M(p): Menge aller in p enthaltenen Elemente, min(p): Element mit geringster Priorität in q M(emptyPQ) = ∅ M(add(p, e)) = M(p) ∪ {e} deletemin(p) = (e, q) → e = min(p) M(q) = M(p) \ {min(p)} 180 Beispiele I Notfallaufnahme Prioritäten: lebensbedrohliche (1), schwere (2), leichte (3) Verletzungen I Verkauf von Olympiakarten Prioritäten: Sportler (1-1000), Sponsoren (1000-2000), Sportlerfamilien (2000-3000), Prominenz (3000-4000), . . . I Betriebssysteme: Scheduling von Prozessen I kürzeste Wege in Graphen (Dijkstra) I Expansionsreihenfolge der Knoten in Spielbäumen 181 Spezielle Priority-Queues Queue Priorität jedes neu in die PQ eingefügten Elementes kleiner (Schlüssel größer) als Maximum aller schon in der PQ enthaltenen Elemente (Einfügen aufsteigend geordneter Schlüsselfolge) Stack Priorität jedes neu in die PQ eingefügten Elementes größer (Schlüssel kleiner) als Maximum aller schon in der PQ enthaltenen Elemente (Einfügen absteigend geordneter Schlüsselfolge) 182 Sortieren mit Priority-Queue Wiederholung: Spezifikation des Sortier-Problemes: Vorbedingung: Eingabe (x1 , x2 , . . . , xn ) mit ∀i ∈ {1, . . . , n} : xi ∈ natürlicher Zahlen Nachbedingung: Ausgabe (y1 , y2 , . . . , yn ) ist 1. y1 < y2 ≤ · · · < yn+1 (aufsteigend geordnet) und 2. eine Permutation (Umordnung) der Eingabe (x1 , x2 , . . . , xn ) Algorithmus zum (aufsteigenden) Sortieren mit Priority-Queue: 1. alle Eingabeelemente x1 , x2 , . . . , xn nacheinander in eine leere PQ einfügen N 1.1 p ← emptyPQ 1.2 für i ← 1, . . . n: p ← add(p, xi ) 2. alle Elemente nacheinander ausgeben und entfernen Wiederholung solange nicht isEmpty(p): 2.1 (e, p) ← deletemin(p) 2.2 Ausgabe e Laufzeit implementierungsabhängig 183 PQ-Implementierung als Liste unsortierte Liste / Folge: I add: zu Beginn oder Ende der Liste / Folge in O(1) I deletemin: Minimum-Suche in O(n) sortierte Liste: I add: (aufsteigend) sortiertes Einfügen in O(n) I deletemin: O(1) 184 PQ-Implementierung als Baum Binäre Suchbäume: Laufzeiten: Tiefe des Baumes I add: sortiertes Einfügen in O(n) I deletemin: O(n) Suchbäume mit geeigneter Balance-Eigenschaft (z.B. AVL-Bäume, b-Bäume, Rot-Schwarz-Bäume): Laufzeiten: Tiefe des Baumes I add: sortiertes Einfügen in O(log n) I deletemin: O(log n) 185 Binäre Heaps Ein Binärbaum t erfüllt die Heap-Eigenschaft: Struktureigenschaft: t ist ein vollständig balancierter Binärbaum d.h. in jedem Knoten Node(x, l, r ) in t gilt: |size(l) − size(r )| ≤ 1 spezielle Heap-Form: Blatt-Schicht „von links vollständig“ belegt Ordnungseigenschaft: t ist Heap-geordnet: in jedem Knoten Node(x, Node(y , l, r ), Node(z, s, t)) in t gilt: x ≤ y und x ≤ z Beispiele (Tafel) Auf jedem Pfad eines Heaps sind die Schlüssel sortiert (aufsteigend von Wurzel zu Blatt) 186 Binärer Heap – add Einfügen eines Schlüssels v : 1. Neuen Knoten mit Schlüssel v auf der ersten freien Position im Heap (Blattebene) einfügen (ggf. neue Blattebene beginnen) Heap-Eigenschaft evtl. verletzt 2. benachbarte Knotenwerte entlang des Pfades vom neu eingefügten Knoten zur Wurzel austauschen, bis Schlüssel auf dem Pfad sortierte Folge bilden Warum erhält diese Operation die Heap-Eigenschaft? Laufzeit: O(log n) (Tiefe des Baumes) 187 Binärer Heap – deletemin Ausgabe und Löschen des Wurzelknotens des Heap: 1. Ausgabe des Wertes in der Wurzel 2. Kopie des Wertes des „letzen“ Blattes in die Wurzel, Löschen des letzten Blattes Heap-Eigenschaft evtl. verletzt 3. beginnend in der Wurzel, Austausch der Knotenwerte von Vaters und dem Sohn mit dem kleinstem Knotenwert Warum erhält diese Operation die Heap-Eigenschaft? Laufzeit: O(log n) (Tiefe des Baumes) 188 Heap-Sort Spezifikation Sortieren (aufsteigend): Vorbedingung: Eingabe (x1 , x2 , . . . , xn ) mit ∀i ∈ {1, . . . , n} : xi ∈ natürlicher Zahlen N Nachbedingung: Ausgabe (y1 , y2 , . . . , yn ) ist 1. y1 ≤ y2 ≤ · · · ≤ yn+1 (aufsteigend geordnet) und 2. eine Permutation (Umordnung) der Eingabe (x1 , x2 , . . . , xn ) Heap-Sort-Algorithmus zum Sortieren: 1. alle Eingabeelemente x1 , x2 , . . . , xn nacheinander in einen leeren binären Heap einfügen (add) Laufzeit für jedes Element O(log n), gesamt O(n log n) 2. alle Elemente nacheinander entfernen und ausgeben (deletemin) Laufzeit für jedes Element O(log n), gesamt O(n log n) Gesamtlaufzeit: O(n log n) 189 Baumdurchquerung mit Priority-Queue Allgemeiner Durchquerungs-Algorithmus: 1. La = {s} (Wurzel s des zu durchquerenden Baumes) 2. solange La 6= ∅ wiederhole: Auswahl und Entfernen eines Knotens u aus La Einfügen aller Kinder von u in La I Verwaltung von La als Priority-Queue I Auswahl des nächsten Knotens: deletemin I Einfügen der Nachbarn: add (mit geeigneter Priorität) Priorität: Bewertung der Knoten (Heuristik) heuristische Suchverfahren (mehr dazu in LV zu Wissensverarbeitung) 190