Datenstrukturen und Algorithmen VO 708.031 29.11.2012 elmar.rueckert@igi.tugraz.at 1
WH: Untere Schranke für SorGeren Die bisher betrachteten schnellen Sor$eralgorithmen (MergeSort, HeapSort, QuickSort) brauchen O(n*log n) Zeit Gibt es einen schnelleren SorGeralgorithmus? Wir zeigen: Jedes SorGerverfahren, das mitels Vergleichen arbeitet, braucht mindestens c n log n Vergleiche im worst case 29.11.2012 elmar.rueckert@igi.tugraz.at 2
Untere Schranke für SorGeren Der Kontrollfluss von vergleichsbasierten SorGerverfahren kann als Entscheidungsbaum dargestellt werden: Beispiel: drei Zahlen a 1, a 2, a 3 : alle möglichen Programmverzweigungen Innere Knoten: Vergleiche zwischen Elementen BläAer: SorGerte Reihenfolge des Inputs Es gibt n! BläTer Ast: Kontrollfluss für best. Input 29.11.2012 elmar.rueckert@igi.tugraz.at 3
Untere Schranke für SorGeren Das worst case Verhalten des Algorithmus entspricht dem längsten Ast im Entscheidungsbaum (# Knoten = # Vergleiche) Der längste Ast wird kürzestmöglich, wenn alle Äste ungefähr gleich lang sind Idealer Algorithmus entspricht einem vollständigen Binärbaum mit n! BläTern 29.11.2012 elmar.rueckert@igi.tugraz.at 4
Untere Schranke für SorGeren Die Höhe eines Binärbaums mit n! BläTern ist Ω(n*log n) Ω(n*log n) ist eine untere Schranke für die Anzahl der im worst case zum SorGeren notwendigen Vergleiche Die worst case Laufzeit vergleichsorien$erter Sor$erverfahren ist Ω(n*log n) MergeSort und HeapSort sind worst case op$mal 29.11.2012 elmar.rueckert@igi.tugraz.at 5
Untere Schranke für SorGeren Gibt es einen schnelleren SorGeralgorithmus? Ja: nicht vergleichsoriengerte SorGeralgorithmen (z.b. RadixSort) Durch Verwendung von ZusatzinformaGon: WerGgkeit einer Dezimalstelle 29.11.2012 elmar.rueckert@igi.tugraz.at 6
RadixSort Beispiel für einen nicht vergleichsoriengerten SorGeralgorithmus SorGeren von n Dezimalzahlen der Länge d: RADIXSORT (A, d) 1: FOR i = 1 TO d 2: Ordne A nach i-ter Ziffer v.h. in Fächer ein (Streuphase) 3: Fasse die Fächer in aufsteigender Reihenfolge wieder in A zusammen (Sammelphase) T(n) = O(d*n) linear, wenn d als konstant betrachtet wird! Nach den ersten k Durchläufen sind die Zahlen, eingeschränkt auf die letzten k Ziffern, sorgert Wich$g: Die vorige Reihenfolge innerhalb der Fächer muss aufrechterhalten werden 29.11.2012 elmar.rueckert@igi.tugraz.at 7
RadixSort Beispiel für einen nicht vergleichsoriengerten SorGeralgorithmus Wenn d nicht konstant: z.b. Auffüllen mit Nullen. 29.11.2012 elmar.rueckert@igi.tugraz.at 8
Eigenschaoen von SorGerverfahren Ein SorGerverfahren ist stabil: Elemente mit idengschen SorGerschlüsseln erscheinen in Input und Output in gleicher Reihenfolge adap$v: (teilweise) vorsorgerte Folgen werden effizienter sorgert (besseres Laufzeitverhalten für fast sorgerte Folgen) worst case op$mal: Jede Eingabefolge wird in O(n*log n) Zeit sorgert (der unteren Schranke für vergleichsbasierte SorGerverfahren) in place: außer für einzelne Variablen (i, j, ) wird kein Zusatzspeicher (Hilfsfelder, ) benöggt 29.11.2012 elmar.rueckert@igi.tugraz.at 9
Vergleich von SorGerverfahren Oo werden KombinaGon verwendet z.b.: für n < 10 InserGon Sort sonst Quick Sort. 29.11.2012 elmar.rueckert@igi.tugraz.at 10
Elementare Datenstrukturen (Tafel mit Keilschrio, Priester von Adab, 4600 Jahre alt) Peru Inca, Aufzeichnungsform [Aus K. Mehlhorn and P. Sanders: Data Structures and Algorithms. Springer Verlag, 2008] 25.10.2012 elmar.rueckert@igi.tugraz.at 11
Gestreute Speicherung (Hashing) Wir suchen eine Datenstruktur, die das Wörterbuchproblem effizient löst Wörterbuchopera$onen: Einfügen Suchen Enyernen Anwendungen: Telefonbuch, Wörterbuch, Symboltabelle beim Kompilieren, Lineares Feld: Einfügen O(1) Zeit, Suchen und Enyernen O(n) Zeit 29.11.2012 elmar.rueckert@igi.tugraz.at 12
Gestreute Speicherung (Hashing) Idee: AnstaT zu suchen, berechne die Adresse eines Datums aus seinem Wert in O(1) Zeit Hashtabelle: lineares Feld T[0..m 1]; Datum mit Wert w wird in T[h(w)] gespeichert Hashfunk$on: h: U {0, 1,, m 1} U = Universum aller möglichen Schlüssel Aktuelle Schlüssel w h(w) = j Kollision h (w) = h (w ) j = 0 j = 1 j = m 2 Hashtabelle T j = m 1 29.11.2012 elmar.rueckert@igi.tugraz.at 13
Gestreute Speicherung (Hashing) Einfaches Beispiel für RadixSort (Tafel) U = Universum aller möglichen Schlüssel Aktuelle Schlüssel w h(w) = j Kollision h (w) = h (w ) j = 0 j = 1 j = m 2 Hashtabelle T j = m 1 29.11.2012 elmar.rueckert@igi.tugraz.at 14
Gestreute Speicherung (Hashing) Die HashfunkGon sollte möglichst wenig Kollisionen liefern Ideale Hashfunk$on: Pr 1 m [ h( w) = j] = w U, j {0,..., m 1} Behandlung von Kollisionen: Überläuferlisten (Chaining) Offene Adressierung Lineare und quadragsche Sondierung Doppeltes Hashing 29.11.2012 elmar.rueckert@igi.tugraz.at 15
Hash FunkGonen Was ist eine gute HashfunkGon? Jeder Index j=0,,m 1 sollte gleichwahrscheinlich sein, um möglichst wenig Kollisionen zu liefern h(w) soll möglichst effizient berechnet werden Ähnliche Werte sollten möglichst gut getrennt werden h(w) soll unabhängig von Mustern in den Daten sein Wir kennen selten die genaue Verteilung der Werte HeurisGsche Wahl der HashfunkGon Wir betrachten h: N {0, 1,, m-1} 29.11.2012 elmar.rueckert@igi.tugraz.at 16
Hash FunkGonen Divisionsmethode: Dividiere den Wert durch m und nimm den Rest: h( w) = wmod m z.b.: w=100, m=12, h(100) = 100 mod 12 = 4 Vorteil: schnell berechenbar Nachteil: nicht für alle m gut m=2 k, m=10 k : hängt nur von den letzten k Bits/Ziffern ab Gut für m Primzahl und nicht zu nahe an 2 k, 10 k 29.11.2012 elmar.rueckert@igi.tugraz.at 17
Hash FunkGonen Mul$plika$onsmethode: MulGpliziere den Wert mit einer fixen Konstante A, 0<A<1, und mulgpliziere den gebrochenen Teil des Resultates mit m: h( w) = m frac( w A) Vorteil: m ist unkrigsch (m=2 k : durch Shio OperaGonen effizient berechenbar) Guter Wert für A: A = 5 1 2 0,6180... 29.11.2012 elmar.rueckert@igi.tugraz.at 18
Behandlung von Kollisionen Überläuferlisten (Chaining) Offene Adressierung Lineare und quadragsche Sondierung Doppeltes Hashing U = Universum aller möglichen Schlüssel Aktuelle Schlüssel w h(w) = j Kollision h (w) = h (w ) j = 0 j = 1 j = m 2 Hashtabelle T j = m 1 29.11.2012 elmar.rueckert@igi.tugraz.at 19
Überläuferlisten (Chaining) Bei einer Kollision werden die Daten in einer verketeten Liste angelegt: Einfügen: Am Beginn der Liste T[h(w)] Suchen: Durchsuchen der Liste T[h(w)] Löschen: Suchen von w, Ausklinken aus Liste T[h(w)] 29.11.2012 elmar.rueckert@igi.tugraz.at 20
Überläuferlisten (Chaining) Bei einer Kollision werden die Daten in einer verketeten Liste angelegt: Erwartete Laufzeit Einfügen: O(1) Suchen: O(1+α) Löschen: O(1+α) α = Worst case: Θ(1+ n) für Suchen, Löschen wenn zufällig alle Werte in dieselbe Liste gestreut 29.11.2012 elmar.rueckert@igi.tugraz.at 21 n m Belegungsfaktor der Hashtabelle O(1+α) = O(1), wenn n=o(m) prob = 1 m n 1
Offene Adressierung AlternaGve Methode zur Behandlung von Kollisionen Alle Werte werden in T[0..m 1] selbst gespeichert α=n/m 1 Bei einer Kollision wird solange eine neue Adresse berechnet, bis ein freier Platz gefunden wird h(w,i) = j i = 1 { 0,1,, m 1} { 0,1,, 1} h : U m i 0,1,2, m 1 Versuchzahl (Probing) noch frei i = 2 besetzt 29.11.2012 elmar.rueckert@igi.tugraz.at 22
Offene Adressierung Ideale Hashfunk$on: Für jeden Wert w ist h(w,0), h(w,1),, h(w,m 1) mit Wahrscheinlichkeit 1/m! eine der m! PermutaGonen von 0, 1,, m 1. In der Praxis verwendete Näherungen: Linear Probing: Problem: benachbarte Felder wahrscheinlicher belegt (primary clustering) Quadra$c Probing: h( w, i) = + h( w, i) = + [ h ( w) i] modm [ h ( w) f ( i) ] modm f(i) quadragsche FunkGon; bei einer Kollision immer noch dieselbe Indexfolge (secondary clustering) Double Hashing: [ h ( w) ih ( w) ] modm h( w, i) = 1 + 2 29.11.2012 elmar.rueckert@igi.tugraz.at 23
Offene Adressierung Einfügen und Suchen: Problem beim Enaernen: Erwartete Laufzeit 1 O 1 α w 1, w 2 eingefügt, w 1 enyernt w 2 wird nicht mehr gefunden enyernte Werte markieren 29.11.2012 elmar.rueckert@igi.tugraz.at 24
Danke für Ihre Aufmerksamkeit! Bis zum nächsten Mal. (Donnerstag, 6. Dez. 2012, 11:15, i13) 29.11.2012 elmar.rueckert@igi.tugraz.at 25