Datenstrukturen und Algorithmen SS07 Datum: 18.4.2007 Michael Belfrage [email protected] belfrage.net/eth Programm von Heute • • • • Nachbesprechung Serie 3 Challenge der Woche binäre Suche vs. Interpolationssuche Hashing – Motivation – offene Adressierung („open hashing“) • lineares Sondieren • quadratisches Sondieren • Double-Hashing – Analyse einiger Hashfunktionen (Aufgabe 4.4) Aufgabe 3.1 (Heapsort) • Vorallem wichtig: – Falls ihr ein Verfahren ohne Begründung verwendet, dann das von der Vorlesung. (Siehe auch die Slides der letzten Woche) Aufgabe 3.2 (Anagramme) Mögliche Lösung: 1. Buchstaben der Wörter sortieren: • • „ANAGRAMM“ zu „AAAGMMNR“ z.B. mit Quicksort 2. Alle Wörter untereinander sortieren • z.B. mit Radix-, Countingoder Bucketsort 3. Liste durchgehen • Anagramme stehen jetzt nebeneinander Aufgabe 3.4 (Sortierverfahren) • Vorsortiertheit = Stabilität – Vorsortiertheit • Falls die Eingabe eher vorsortiert ist – z.B. [1,2,3,4,5,6,8,7] – Stabilität • Falls die relative Reihenfolge von gleichen Eingabeelementen bewahrt wird – [2,1,2,4,3,2] vor dem Sortieren – [1,2,2,2,3,4] nach dem Sortieren Aufgabe 3.4 (Sortierverfahren) • Selectionsort ist nicht geeignet für vorsortierte Daten: – Wir müssen jeweils alle n-i Elemente ansehen im i-ten Durchgang um das kleinste Element zu finden, egal wie vorsortiert die Eingabe ist. – Hingegen müssen weniger Swaps gemacht werden, wenn sie vorsortiert sind. [gleichwohl O(n2) Vergleiche] Aufgabe 3.4 (Sortierverfahren) • Ist Quicksort geeignet falls wenig zusätzlicher Speicher vorliegt? – Rekursive Variante macht n rekursive Aufrufe im worst-case • Speicher: const • n = O(n) – Können wir das optimieren? • Ja! Wir können die rekursiven Aufrufe auf log(n) beschränken Aufgabe 3.4 (Sortierverfahren) • Quicksort(F) is Falls F mehr als 1 Element hat: – Divide • Pivot bestimmen • F mittels Pivot aufteilen in F1 und F2 – Conquer • Quicksort(F1); Quicksort(F2); – Merge Aufgabe 3.4 (Sortierverfahren) • Quicksort(F,l,r) – If (l<r) – Then is l r • Divide F – Pivot bestimmen – F mittels Pivot aufteilen von l bis r (dabei wird Pivot zwischen Teile gesetzt) – l1,r1 und l2,r2 bestimmen • Conquer – Quicksort(F,l1,r1); Quicksort(F,l2,r2); – End l1 r1 P F l2 r2 Aufgabe 3.4 (Sortierverfahren) • Quicksort(F,l,r) – Solange (l<r) – loop • Divide – Pivot bestimmen – F mittels Pivot aufteilen von l bis r (dabei wird Pivot zwischen Teile gesetzt) – l1,r1 und l2,r2 bestimmen • Conquer – end – if Intervall(l1,r1) < Intervall(l2,r2) then Quicksort(F,l1,r1) l:= l2 else Quicksort(F,l2,r2); r:= r1 end r1 P l2 l1 F r2 The Challenge • Gegeben ist: – ein sortiertes Array A bestehend aus n Zahlen – eine Zahl x • Bestimme in O(n) Zeit und mit O(1) zusätzlichem Speicher, ob es zwei Zahlen z1 und z2 aus A gibt, deren Summe x ist. • Beispiel: – Input: • A := [-27,-6,-3,8,12,19,42] • x := 27 – Output: • Ja (z.B. z1=8 und z2=19) binäre Suche vs. Interpolationssuche • Sei A ein sortiertes Array • Wir suchen nun binär nach einem Element x an einem Beispiel: • x = 78 • A = [8,16,49,75,78,94,97] binäre Suche vs. Interpolationssuche • Sei A ein sortiertes Array • Wir suchen nun binär nach einem Element x an einem Beispiel: • x = 78 • A = [8,16,49,75,78,94,97] binäre Suche vs. Interpolationssuche • Sei A ein sortiertes Array • Wir suchen nun binär nach einem Element x an einem Beispiel: • x = 78 • A = [8,16,49,75,78,94,97] binäre Suche vs. Interpolationssuche • Sei A ein sortiertes Array • Wir suchen nun binär nach einem Element x an einem Beispiel: • x = 78 • A = [8,16,49,75,78,94,97] binäre Suche vs. Interpolationssuche • Sei A ein sortiertes Array • Wir suchen nun binär nach einem Element x an einem Beispiel: • x = 78 • A = [8,16,49,75,78,94,97] binäre Suche vs. Interpolationssuche • Sei A ein sortiertes Array • Wir suchen nun binär nach einem Element x an einem Beispiel: • x = 78 • A = [8,16,49,75,78,94,97] binäre Suche vs. Interpolationssuche • Sei A ein sortiertes Array • Binäre Suche nach einem Element x geht folgendermassen: – Vergleiche x mit dem Median von A • Ist x kleiner, – dann suche links vom Median weiter • Ist x grösser, – dann suche rechts vom Median weiter • Sonst haben wir x gefunden und sind fertig. binäre Suche vs. Interpolationssuche • Sei A ein sortiertes Array • Binäre Suche in Pseudocode: search(A,x) l := 1 r := Anzahl Elemente von A Solange (l <= r) loop m := (l + r) / 2 if (A[m] < x) then l := m + 1 else if (A[m] > x) then r := m - 1 else Result:= „x gefunden“ end end Result:= „x nicht gefunden“ Um einen Überlauf zu verhindern könnte man diese Zeile umändern in: m := (l+(r-l)/2) Die binäre Suche hat eine Laufzeit von O(log(n)). binäre Suche vs. Interpolationssuche • Sei A ein sortiertes Array • Bei der Interpolationssuche geht man analog zur binären Suche vor, mit dem Unterschied, dass man statt dem Median, jeweils die Position wählt, wo das x ungefähr sein sollte, falls die Daten linear verteilt wären. • In Zahlen: x−A[l] m = l + (r − l) · A[r]−A[l] binäre Suche vs. Interpolationssuche • Die Interpolationssuche braucht im Mittel O(log(log(n)))Vergleiche • Falls die Daten jedoch überhaupt nicht linear wachsen, kann sie aber auch bis zu O(n) Vergleich benötigen • Wann z.B. ? binäre Suche vs. Interpolationssuche Zusammenfassend: • Wann ist die Interpolationssuche der binären Suche vorzuziehen? – Wenn die Werte im Array ungefähr linear wachsen • z.B. Wörterbuch, Telefonkatalog, etc. • Wann ist die binäre Suche geeignet? – Im Normalfall, d.h. wenn man sich ziemlich sicher ist, dass die Daten nicht linear wachsen. binäre Suche vs. Interpolationssuche • Aufgabe 4.2 (b) – Binäre- und Interpolationssuche kombinieren – Dazu wählen wir jeweils als Pivot abwechslungsweise einmal den Median und einmal die Position nach Definition der Interpolationsuche. – Somit haben wir im schlimmsten Fall immer noch maximal die zweifache Laufzeit der binären Suche, was immer noch O(log(n)) entspricht. Hashing • Motivation: – Wartung einer grossen Datenmenge, um Elemente zu: • Suchen • Einfügen • Löschen Hashing Suchen, Einfügen, Löschen • Wieso „Hashing“? • Wir haben ja z.B.: – Linked List • Suchen laaaangsam – Array [unsortiert] • Suchen und Löschen laaaangsam – Array [sortiert] • Einfügen und Löschen laaaangsam – Irgendwelche Bäume • Ok.... Aber meist komplex umzusetzen, und Operationen um die O(log(n)) Zeit. Hashing • Wir sehen uns also einen neuen Ansatz an: HASHING ! – Einfügen, Löschen UND Suchen in erwarteter Zeit von Θ(1) !!! • Wie soll das gehen? Hashing • Speicherplatz: ... 0 1 2 3 m-4 m-3 m-2 Hashtabelle mit m Felder m-1 Hashing • Datensätze: NN: Diederick Diederick NN: NN: Diederick NN: Diederick VN: Mathias NN: Diederick Mathias VN:NN:VN: Mathias Diederick VN: Mathias NN: Diederick NN: Diederick LegiNr: 03-125-521 VN: Mathias NN: Diederick 03-125-521 LegiNr: 03-125-521 VN:LegiNr: Mathias NN: Diederick LegiNr: 03-125-521 VN: Mathias VN: Mathias NN: Raimund NN: Diederick Login: mdied LegiNr: 03-125-521 VN: Mathias NN: Raimund NN: Diederick Login: mdied Login: mdied LegiNr: 03-125-521 VN: Mathias Login: mdied LegiNr: 03-125-521 LegiNr: 03-125-521 VN: Heinz VN: Mathias NN: Diederick Fach: INFK Login: mdied LegiNr: 03-125-521 VN: Heinz VN: Mathias NN: Diederick Fach: INFK Fach: INFK Login: mdied LegiNr: 03-125-521 Fach: INFK NN: Waldemar Login: mdied Login: mdied LegiNr: 01-215-622 LegiNr: 03-125-521 Mathias NN: ... Waldemar Fach: INFK Login: mdied LegiNr: VN: 01-215-622 LegiNr: 03-125-521 VN: Fach: Mathias ... ... INFK Login: mdied ... VN: Eduard Fach: INFK Fach: INFK Login: heinzr Login: mdied 03-125-521 VN: Eduard ... Fach: INFK Login: LegiNr: heinzr Login: mdied LegiNr: 03-125-521 ... Fach: INFK LegiNr: 02-520-315 ... ... Fach: INFK Fach: INFK mdied ... Fach: Login: INFK Fach:LegiNr: INFK02-520-315 Login: mdied ... Login: ewalde ... ... Fach: INFK ... Login: ... ewalde Fach: INFK Fach: INFK ... Fach: ... INFK ... ... Hashing • Möglicher Ansatz zum einfügen der Datensätze: 0 1 2 3 m-4 m-3 m-2 m-1 ... Problem: NN: Fröhlich NN: Fröhlich VN: Frida NN: Waldemar VN: Frida NN: Waldemar LegiNr: 03-515-521 VN: Eduard LegiNr: 03-515-521 VN: Eduard Login: LegiNr: 02-520-315 Login: ffrida ffrida LegiNr: 02-520-315 Fach: INFK Login: ewalde Fach: INFK Login: ewalde ...... Fach: INFK Raimund Fach: INFK NN: NN: Raimund ...... VN: VN: Heinz Heinz LegiNr: 01-215-622 LegiNr: 01-215-622 Login: Login: heinzr heinzr Fach: Fach: INFK INFK ...... Obwohl effizient zum einfügen, würde die Suche nach einem Datensatz laaaaaaang gehen... Hashing Wir bestimmen stattdessen einen eindeutigen Schlüssel für jeden Datensatz: NN: NN: NN: Diederick Diederick Diederick NN: Diederick NN: Diederick VN: Mathias NN: Diederick VN: VN: NN: Mathias Diederick Mathias VN: Mathias VN: Mathias NN: Raimund NN: Diederick 03-125-521 VN: Mathias NN: Raimund NN:LegiNr: Diederick LegiNr: 03-125-521 VN: Mathias LegiNr: 03-125-521 LegiNr: 03-125-521 LegiNr: 03-125-521 VN: Heinz VN: Mathias NN: Diederick mdied LegiNr: 03-125-521 VN: Heinz VN:Login: Mathias NN: Diederick Login: mdied LegiNr: 03-125-521 Login: mdied NN: Waldemar Login: mdied Login: mdied LegiNr: 01-215-622 LegiNr: 03-125-521 VN: Mathias NN: Waldemar Fach: INFK Login: mdied LegiNr: VN: 01-215-622 LegiNr: 03-125-521 Mathias Fach: INFK Login: mdied Fach: INFK VN: Eduard Fach: INFK Fach: INFK Login: heinzr Login: mdied 03-125-521 VN: Eduard ... Fach: INFK Login: LegiNr: heinzr Login: mdied LegiNr: 03-125-521 ... Fach: INFK ... LegiNr: 02-520-315 ... ... Fach: INFK Fach: INFK mdied LegiNr: 02-520-315 ... Fach: Login: INFK Fach: INFK Login: mdied ... Login: ewalde ... ... Fach: INFK ... Login: ... ewalde Fach: INFK Fach: INFK ... Fach: ... INFK ... ... h(k) 132 Datensätze mit sehr vielen möglichen Schlüsseln. Genauer: 26 Buchstaben mit max. 15 Zeichen: d.h. 2716-2 = ca. 1023 Möglichkeiten für den Schlüssel. Hashing Eine Hashfunktion h: {a,...,zz•••zz} {0,...,m-1} 0 1 ewalde fssas ... ffrida gbsa sfw zachzaff m-1 h(k) Universum {a,b,...,aa,ab, ..., zz•••zz} grosse Menge Hash-Tabelle {0 ... m-1} kleine Menge Hashing • Was tun bei Kollisionen? – Sondieren, z.B. • Linear • Quadratisch • Mittels einer zweiten Hashfunktion (= Double Hashing) Lineares Sondieren • Nach j erfolglosen Versuchen testen ob „(h(k)-j) mod m“ noch frei ist 0 1 2 3 4 5 6 m-1 ... NN: Waldemar NN: Waldemar VN: VN: Eduard Eduard LegiNr: LegiNr:02-520-315 02-520-315 Login: Login: ewalde ewalde Fach: INFK Fach: INFK ... ... h(„ewalde“) = 5 h(„ewalde“) - 1 = 4 h(„ewalde“) - 2 = 3 NN: Fröhlich NN: Fröhlich VN: Frida VN: Frida LegiNr: LegiNr:03-515-521 03-515-521 Login: Login: ffrida ffrida Fach: INFK Fach: INFK ... ... NN: NN: Raimund Raimund VN: VN: Heinz Heinz LegiNr: 01-215-622 LegiNr: 01-215-622 Login: Login: heinzr heinzr Fach: Fach: INFK INFK ... ... Quadratisches Sondieren • Bei Kollision nacheinander: h(k) + 12 , h(k) – 12 , h(k) + 22 , h(k) – 22 , h(k) + 32 , h(k) – 32 , ... etc. mod m probieren, bis ein freies Feld erreicht wird. Double Hashing • Sei h‘(k) eine zweite Hashfunkion • Dann nach j-ter Kollision jeweils mit (h(k) – j•h‘(k)) mod m probieren. Hashing • Was macht eine gute Hashfunktion h(k) aus? – Einfach berechenbar – Wenige Kollisionen • d.h. h(k1)=h(k2) sollte selten vorkommen für k1, k2 welche wir in die Hashtabelle einfügen Aufgabe 4.4 • Universum = {0,1,2,...} • Hashtabelle mit p Einträgen, wobei p eine Primzahl ist. • Hashfunktion h(k)= k mod p • q ist die grösste Primzahl kleiner p • vollständige Hashfunktion bei der j-ten Sondierung ist jeweils: h(k) – j•h‘(k) bzw. h(k) – s(j,k) Aufgabe 4.4a Ist die folgende Funktion als Hashfunktion brauchbar? h‘(k) = k · p mod p Aufgabe 4.4b Ist die folgende Funktion als Hashfunktion brauchbar? h‘(k) = ⌊(p − 1) · (k · r − ⌊k · r⌋)⌋ + 1, + wobei r ∈ R \ Q Aufgabe 4.4c Ist die folgende Funktion als Hashfunktion brauchbar? h‘(k) = ln(k) mod p Aufgabe 4.4d Ist die folgende Funktion als Hashfunktion brauchbar? h‘(k) = ((37 · k + 23) mod q) + 1 Aufgabe 4.4e Ist die folgende Funktion als Hashfunktion brauchbar? s(j, k) = k j mod q Aufgabe 4.4f Ist die folgende Funktion als Hashfunktion brauchbar? s(j, k) = ((k + j) mod p) + 1 Aufgabe 4.4g Ist die folgende Funktion als Hashfunktion brauchbar? s(j, k) = ((k · j) mod q) + 1 Ende der Stunde. Questions?