1 / 95

Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)

Datenstrukturen, Algorithmen und Programmierung 2 (DAP2). Datenstrukturen. Hashing Universum U={0,..,m-1} Hash Tabelle T[0,..,t-1] Hash Funktion h: U  {0,..,t-1} Speichere Element mit Schlüssel k in h(k). Feld T. 0. 1. 2. Universum U. h(k )=2. 6. k. k. k. 10. 7. 9. k. 1.

galen
Télécharger la présentation

Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)

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. Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)

  2. Datenstrukturen Hashing • Universum U={0,..,m-1} • Hash Tabelle T[0,..,t-1] • Hash Funktion h: U  {0,..,t-1} • Speichere Element mit Schlüssel k in h(k) Feld T 0 1 2 Universum U h(k )=2 6 k k k 10 7 9 k 1 k 5 k h(k )=5 2 3 k k k 4 6 3 h(k )=h(k )=6 k 4 8 8 Genutzte Schlüsselmenge 7

  3. Datenstrukturen Hashing • Universum U={0,..,m-1} • Hash Tabelle T[0,..,t-1] • Hash Funktion h: U  {0,..,t-1} • Speichere Element mit Schlüssel k in h(k) Feld T 0 1 2 Universum U h(k )=2 6 k k k 10 7 9 k 1 k 5 k h(k )=5 2 3 k k k 4 6 3 h(k )=h(k )=6 Kollision! k 4 8 8 Genutzte Schlüsselmenge 7

  4. Datenstrukturen Hashing mit Verkettung • Universum U={0,..,m-1} • Hash Tabelle T[0,..,t-1] • Hash Funktion h: U  {0,..,t-1} • Speichere Element mit Schlüssel k in h(k) • Löse Kollisionen durch Listen auf (wie vorhin) Feld T 0 1 2 Universum U 6 k k k 10 7 9 k 1 k 5 k 2 3 k k k 4 6 3 k 8 8 4 Genutzte Schlüsselmenge 7

  5. Datenstrukturen Operationen Einfügen(k) • Füge neuen Schlüssel k am Ende der Liste T[h(k)] ein Löschen(x) • Lösche Element x aus Liste T[h(key[x])] Suche(k) • Suche nach k in Liste T[h(k)]

  6. Datenstrukturen Idee • Wähle h zufällig (aus einer Menge von geeigneten Kandidaten H)

  7. Datenstrukturen Universelles Hashing • Sei H eine Menge von Hashfunktionen von U nach {0,..,t-1}. Die Menge H heißt universell, wenn für jedes Paar von unterschiedlichen Schlüsseln x,yU gilt,dass die Anzahl der Funktion hH mit h(x)=h(y) genau |H|/t ist. Anders gesagt: • Wenn man x und y vorgibt und dann ein zufälliges hH wählt, so ist die Kollisionswahrscheinlichkeit von x und y genau 1/t • Oder: Die durchschnittliche Anzahl Kollisionen (über H) von x und y ist 1/t

  8. Datenstrukturen Satz 43 • Sei MU eine Menge von n Schlüsseln, T eine Tabelle mit t≥n Einträgen und sei H eine universelle Klasse von Hashfunktionen von U nach {0,..,t-1}. Wenn h ausH zufällig ausgewählt wird und danach zum Speichern von M in T benutzt wird, so ist die durchschnittliche Anzahl Kollisionen eines vorher festgelegten Schlüssels x höchstens 1.

  9. Datenstrukturen Satz 43 • Sei MU eine Menge von n Schlüsseln, T eine Tabelle mit t≥n Einträgen und sei H eine universelle Klasse von Hashfunktionen von U nach {0,..,t-1}. Wenn h aus H zufällig ausgewählt wird und danach zum Speichern von M in T benutzt wird, so ist die durchschnittliche Anzahl Kollisionen eines vorher festgelegten Schlüssels x höchstens 1. Beweis • Für jedes Paar y,z sei c(y,z)=1, wenn h(y)=h(z) gilt

  10. Datenstrukturen Satz 43 • Sei MU eine Menge von n Schlüsseln, T eine Tabelle mit t≥n Einträgen und sei H eine universelle Klasse von Hashfunktionen von U nach {0,..,t-1}. Wenn h aus H zufällig ausgewählt wird und danach zum Speichern von M in T benutzt wird, so ist die durchschnittliche Anzahl Kollisionen eines vorher festgelegten Schlüssels x höchstens 1. Beweis • Für jedes Paar y,z sei c(y,z)=1, wenn h(y)=h(z) gilt • Der durchschn. Wert E[c(y,z)] von c(y,z) (über H) ist 1/t

  11. Datenstrukturen Satz 43 • Sei MU eine Menge von n Schlüsseln, T eine Tabelle mit t≥n Einträgen und sei H eine universelle Klasse von Hashfunktionen von U nach {0,..,t-1}. Wenn h ausH zufällig ausgewählt wird und danach zum Speichern von M in T benutzt wird, so ist die durchschnittliche Anzahl Kollisionen eines vorher festgelegten Schlüssels x höchstens 1. Beweis • Für jedes Paar y,z sei c(y,z)=1, wenn h(y)=h(z) gilt • Der durchschn. Wert E[c(y,z)] von c(y,z) (über H) ist 1/t • Sei nun C(x) die Anzahl Kollisionen mit Schlüssel x, d.h. • C(x) = S c(x,y) yM,yx

  12. Datenstrukturen Beweis • Für jedes Paar y,z sei c(y,z)=1, wenn h(y)=h(z) gilt • Der durchschn. Wert E[c(y,z)] von c(y,z) (über H) ist 1/t • Sei nun C(x) die Anzahl Kollisionen mit Schlüssel x, d.h. • C(x) = S c(x,y) yM,yx

  13. Datenstrukturen Beweis • Für jedes Paar y,z sei c(y,z)=1, wenn h(y)=h(z) gilt • Der durchschn. Wert E[c(y,z)] von c(y,z) (über H) ist 1/t • Sei nun C(x) die Anzahl Kollisionen mit Schlüssel x, d.h. • C(x) = S c(x,y) • Damit ist der durchschn. Wert E[C(x)] von C(x) • E[C(x)] = SE[c(x,y)] ≤ n / t yM,yx yM ,yx

  14. Datenstrukturen Beweis • Für jedes Paar y,z sei c(y,z)=1, wenn h(y)=h(z) gilt • Der durchschn. Wert E[c(y,z)] von c(y,z) (über H) ist 1/t • Sei nun C(x) die Anzahl Kollisionen mit Schlüssel x, d.h. • C(x) = S c(x,y) • Damit ist der durchschn. Wert E[C(x)] von C(x) • E[C(x)] = SE[c(x,y)] ≤ n / t • Da n≤t folgt E[C(x)] ≤ 1. yM,yx yM ,yx

  15. Datenstrukturen Beweis • Für jedes Paar y,z sei c(y,z)=1, wenn h(y)=h(z) gilt • Der durchschn. Wert E[c(y,z)] von c(y,z) (über H) ist 1/t • Sei nun C(x) die Anzahl Kollisionen mit Schlüssel x, d.h. • C(x) = S c(x,y) • Damit ist der durchschn. Wert E[C(x)] von C(x) • E[C(x)] = SE[c(x,y)] ≤ n / t • Da n≤t folgt E[C(x)] ≤ 1. yM,yx yM ,yx

  16. Datenstrukturen Konstruktion von H (ohne Beweis) • Setze Tabellengröße t auf Primzahl

  17. Datenstrukturen Konstruktion von H (ohne Beweis) • Setze Tabellengröße t auf Primzahl • Teile Schlüssel x in r+1 bytes x , x ,…, x auf, so dass(a) x=<x , x ,…, x > und(b) jedes Byte Maximalwert höchstens t hat 0 1 r 0 1 r

  18. Datenstrukturen Konstruktion von H (ohne Beweis) • Setze Tabellengröße t auf Primzahl • Teile Schlüssel x in r+1 bytes x , x ,…, x auf, so dass(a) x=<x , x ,…, x > und(b) jedes Byte Maximalwert höchstens t hat • Sei a=<a , a ,…, a > Sequenz von r+1 zufälligen Werten aus {0,…,t-1} 0 1 r 0 1 r r 1 0

  19. Datenstrukturen Konstruktion von H (ohne Beweis) • Setze Tabellengröße t auf Primzahl • Teile Schlüssel x in r+1 bytes x , x ,…, x auf, so dass(a) x=<x , x ,…, x > und(b) jedes Byte Maximalwert höchstens t hat • Sei a=<a , a ,…, a > Sequenz von r+1 zufälligen Werten aus {0,…,t-1} • Definiere Hashfunktion h H: • h (x) = S a ∙x mod t 0 1 r 0 1 r r 1 0 a a i i

  20. Datenstrukturen Konstruktion von H (ohne Beweis) • Setze Tabellengröße t auf Primzahl • Teile Schlüssel x in r+1 bytes x , x ,…, x auf, so dass(a) x=<x , x ,…, x > und(b) jedes Byte Maximalwert höchstens t hat • Sei a=<a , a ,…, a > Sequenz von r+1 zufälligen Werten aus {0,…,t-1} • Definiere Hashfunktion h H: • h (x) = S a ∙x mod t • Damit ist H die Vereinigung der h und |H| = t 0 1 r 0 1 r r 1 0 a a i i r+1 a

  21. Datenstrukturen Konstruktion von H (ohne Beweis) • Setze Tabellengröße t auf Primzahl • Teile Schlüssel x in r+1 bytes x , x ,…, x auf, so dass(a) x=<x , x ,…, x > und(b) jedes Byte Maximalwert höchstens t hat • Sei a=<a , a ,…, a > Sequenz von r+1 zufälligen Werten aus {0,…,t-1} • Definiere Hashfunktion h H: • h (x) = S a ∙x mod t • Damit ist H die Vereinigung der h und |H| = t • Funktioniert bis Universumsgröße t 0 1 r 0 1 r r 1 0 a a i i r+1 a r+1

  22. Datenstrukturen Konstruktion von H (ohne Beweis) • Setze Tabellengröße t auf Primzahl • Teile Schlüssel x in r+1 bytes x , x ,…, x auf, so dass(a) x=<x , x ,…, x > und(b) jedes Byte Maximalwert höchstens t hat • Sei a=<a , a ,…, a > Sequenz von r+1 zufälligen Werten aus {0,…,t-1} • Definiere Hashfunktion h H: • h (x) = S a ∙x mod t • Damit ist H die Vereinigung der h und |H| = t • Funktioniert bis Universumsgröße t • Also |H|  |U|, d.h. wir benötigen bei guter Speicherung soviel Bits um |H| zu speichern wie ein Schlüssel aus U groß ist 0 1 r 0 1 r r 1 0 a a i i r+1 a r+1

  23. Datenstrukturen Konstruktion von H (ohne Beweis) • Setze Tabellengröße t auf Primzahl • Teile Schlüssel x in r+1 bytes x , x ,…, x auf, so dass(a) x=<x , x ,…, x > und(b) jedes Byte Maximalwert höchstens t hat • Sei a=<a , a ,…, a > Sequenz von r+1 zufälligen Werten aus {0,…,t-1} • Definiere Hashfunktion h H: • h (x) = S a ∙x mod t • Damit ist H die Vereinigung der h und |H| = t • Funktioniert bis Universumsgröße t • Also |H|  |U|, d.h. wir benötigen bei guter Speicherung soviel Bits um |H| zu speichern wie ein Schlüssel aus U groß ist 0 1 r 0 1 r r 1 0 a a i i r+1 a r+1

  24. Datenstrukturen Zusammenfassung • Hashing nutzt Vorteil der direkten Addressierung (O(1) Suchzeit), reduziert aber gleichzeitig den Speicherbedarf auf O(n) • Hashfunktion kann zufällig aus universeller Klasse von Hashfunktionen gewählt werden • Dies garantiert durchschnittliche Suchzeit O(1)

  25. Datenstrukturen Prioritätenschlangen • Einfügen, Löschen, Maximum (bzw. Minimum) • Wir könnten AVL-Bäume benutzen • Gibt es einfachere Datenstruktur? • Gibt es effizientere Datenstruktur? (Ja, aber nicht in dieser Vorlesung) Anwendungen • Ereignisgesteuerte Simulationen • Sortieren mit Heapsort

  26. Datenstrukturen Binäre Halden • Feld A[1,…,length[A]] • Man kann Feld als vollständigen Binärbaum interpretieren • D.h., alle Ebenen des Baums sind voll bis auf die letzte • Zwei Attribute: length[A] und heap-size[A],heap-size  length[A] 1 15 4 3 5 2 1 6 3 2 12 10 6 5 4 3 2 7

  27. Datenstrukturen Navigation • Wurzel ist A[1] Parent(i) 1. returni/2 Left(i) 1. return 2i Right(i) 1. return 2i+1 1 15 4 3 5 2 1 6 3 2 12 10 6 5 4 3 2 7

  28. Datenstrukturen Navigation • Wurzel ist A[1] Parent(i) 1. returni/2 Left(i) 1. return 2i Right(i) 1. return 2i+1 1 15 4 3 5 2 1 6 3 2 12 10 6 5 4 3 2 7

  29. Datenstrukturen Navigation • Wurzel ist A[1] Parent(i) 1. returni/2 Left(i) 1. return 2i Right(i) 1. return 2i+1 1 15 4 3 5 2 1 6 3 2 12 10 6 5 4 3 2 7

  30. Datenstrukturen Navigation • Wurzel ist A[1] Parent(i) 1. returni/2 Left(i) 1. return 2i Right(i) 1. return 2i+1 1 15 4 3 5 2 1 6 3 2 12 10 6 5 4 3 2 7

  31. Datenstrukturen Navigation • Wurzel ist A[1] Parent(i) 1. returni/2 Left(i) 1. return 2i Right(i) 1. return 2i+1 1 15 4 3 5 2 1 6 3 2 12 10 6 5 4 3 2 7

  32. Datenstrukturen Navigation • Wurzel ist A[1] Parent(i) 1. returni/2 Left(i) 1. return 2i Right(i) 1. return 2i+1 1 15 4 3 5 2 1 6 3 2 12 10 6 5 4 3 2 7

  33. Datenstrukturen Haldeneigenschaft • Für jeden Knoten i außer der Wurzel gilt A[Parent(i)]A[i] 1 15 4 3 5 2 1 6 3 2 12 10 6 5 4 3 2 7

  34. Datenstrukturen Die Operation Heapify(A,i) • Voraussetzung: Die Binärbäume, mit Wurzel Left(i) und Right(i) sind Halden • A[i] ist aber evtl. kleiner als seine Kinder • Heapify(A,i) lässt i „absinken“, so dass die Haldeneigenschaft erfüllt wird i Halde Halde

  35. Datenstrukturen 4 3 5 2 1 6 Heapify(A,i) 1. l  left(i) 2. r  right(i) 3. if lheap-size[A] and A[l]>A[i] then largest  l 4. else largest  i 5. if rheap-size[A] and A[r]>A[largest] then largest  r 6.if largesti then A[i]  A[largest] 7. Heapify(A,largest) 1 4 3 2 12 10 6 5 4 3 2 7

  36. Datenstrukturen 4 3 5 2 1 6 Heapify(A,i) 1. l  left(i) 2. r  right(i) 3. if lheap-size[A] and A[l]>A[i] then largest  l 4. else largest  i 5. if rheap-size[A] and A[r]>A[largest] then largest  r 6.if largesti then A[i]  A[largest] 7. Heapify(A,largest) i 1 4 3 2 12 10 6 5 4 3 2 7 Heapify(A,1)

  37. Datenstrukturen 4 3 5 2 1 6 Heapify(A,i) 1. l  left(i) 2. r  right(i) 3. if lheap-size[A] and A[l]>A[i] then largest  l 4. else largest  i 5. if rheap-size[A] and A[r]>A[largest] then largest  r 6.if largesti then A[i]  A[largest] 7. Heapify(A,largest) i l 1 4 3 l=2 12 10 6 5 4 3 2 7 Heapify(A,1)

  38. Datenstrukturen 4 3 5 2 1 6 Heapify(A,i) 1. l  left(i) 2. r  right(i) 3. if lheap-size[A] and A[l]>A[i] then largest  l 4. else largest  i 5. if rheap-size[A] and A[r]>A[largest] then largest  r 6.if largesti then A[i]  A[largest] 7. Heapify(A,largest) r i l 1 4 r=3 l=2 12 10 6 5 4 3 2 7 Heapify(A,1)

  39. Datenstrukturen 4 3 5 2 1 6 Heapify(A,i) 1. l  left(i) 2. r  right(i) 3. if lheap-size[A] and A[l]>A[i] then largest  l 4. else largest  i 5. if rheap-size[A] and A[r]>A[largest] then largest  r 6.if largesti then A[i]  A[largest] 7. Heapify(A,largest) r i l 1 4 r=3 l=2 12 10 6 5 4 3 2 7 Heapify(A,1)

  40. Datenstrukturen 4 3 5 2 1 6 Heapify(A,i) 1. l  left(i) 2. r  right(i) 3. if lheap-size[A] and A[l]>A[i] then largest  l 4. else largest  i 5. if rheap-size[A] and A[r]>A[largest] then largest  r 6.if largesti then A[i]  A[largest] 7. Heapify(A,largest) r i l 1 4 r=3 l=2 12 10 6 5 4 3 2 7 Heapify(A,1)

  41. Datenstrukturen 4 3 5 2 1 6 Heapify(A,i) 1. l  left(i) 2. r  right(i) 3. if lheap-size[A] and A[l]>A[i] then largest  l 4. else largest  i 5. if rheap-size[A] and A[r]>A[largest] then largest  r 6.if largesti then A[i]  A[largest] 7. Heapify(A,largest) i 1 12 3 2 4 10 6 5 4 3 2 7 Heapify(A,1)

  42. Datenstrukturen 4 3 5 2 1 6 Heapify(A,i) 1. l  left(i) 2. r  right(i) 3. if lheap-size[A] and A[l]>A[i] then largest  l 4. else largest  i 5. if rheap-size[A] and A[r]>A[largest] then largest  r 6.if largesti then A[i]  A[largest] 7. Heapify(A,largest) i l 1 12 3 2 4 10 6 5 l=4 3 2 7 Heapify(A,1)

  43. Datenstrukturen 4 3 5 2 1 6 Heapify(A,i) 1. l  left(i) 2. r  right(i) 3. if lheap-size[A] and A[l]>A[i] then largest  l 4. else largest  i 5. if rheap-size[A] and A[r]>A[largest] then largest  r 6.if largesti then A[i]  A[largest] 7. Heapify(A,largest) i r l 1 12 3 2 4 10 6 r=5 l=4 3 2 7 Heapify(A,1)

  44. Datenstrukturen 4 3 5 2 1 6 Heapify(A,i) 1. l  left(i) 2. r  right(i) 3. if lheap-size[A] and A[l]>A[i] then largest  l 4. else largest  i 5. if rheap-size[A] and A[r]>A[largest] then largest  r 6.if largesti then A[i]  A[largest] 7. Heapify(A,largest) i r l 1 12 3 2 4 10 6 r=5 l=4 3 2 7 Heapify(A,1)

  45. Datenstrukturen 4 3 5 2 1 6 Heapify(A,i) 1. l  left(i) 2. r  right(i) 3. if lheap-size[A] and A[l]>A[i] then largest  l 4. else largest  i 5. if rheap-size[A] and A[r]>A[largest] then largest  r 6.if largesti then A[i]  A[largest] 7. Heapify(A,largest) i r l 1 12 3 2 4 10 6 r=5 l=4 3 2 7 Heapify(A,1)

  46. Datenstrukturen 4 3 5 2 1 6 Heapify(A,i) 1. l  left(i) 2. r  right(i) 3. if lheap-size[A] and A[l]>A[i] then largest  l 4. else largest  i 5. if rheap-size[A] and A[r]>A[largest] then largest  r 6.if largesti then A[i]  A[largest] 7. Heapify(A,largest) i r l 1 12 3 2 4 10 6 r=5 l=4 3 2 7 Heapify(A,1)

  47. Datenstrukturen 4 3 5 2 1 6 Heapify(A,i) 1. l  left(i) 2. r  right(i) 3. if lheap-size[A] and A[l]>A[i] then largest  l 4. else largest  i 5. if rheap-size[A] and A[r]>A[largest] then largest  r 6.if largesti then A[i]  A[largest] 7. Heapify(A,largest) i r l 1 12 3 2 7 10 6 r=5 l=4 3 2 4 Heapify(A,1)

  48. Datenstrukturen 4 3 5 2 1 6 Heapify(A,i) 1. l  left(i) 2. r  right(i) 3. if lheap-size[A] and A[l]>A[i] then largest  l 4. else largest  i 5. if rheap-size[A] and A[r]>A[largest] then largest  r 6.if largesti then A[i]  A[largest] 7. Heapify(A,largest) i r l 1 12 3 2 7 10 6 r=5 l=4 3 2 4 Heapify(A,1)

  49. Datenstrukturen 4 3 5 2 1 6 Heapify(A,i) 1. l  left(i) 2. r  right(i) 3. if lheap-size[A] and A[l]>A[i] then largest  l 4. else largest  i 5. if rheap-size[A] and A[r]>A[largest] then largest  r 6.if largesti then A[i]  A[largest] 7. Heapify(A,largest) i 1 12 3 2 7 10 6 5 4 3 2 4 Heapify(A,1)

  50. Datenstrukturen 4 3 5 2 1 6 Heapify(A,i) 1. l  left(i) 2. r  right(i) 3. if lheap-size[A] and A[l]>A[i] then largest  l 4. else largest  i 5. if rheap-size[A] and A[r]>A[largest] then largest  r 6.if largesti then A[i]  A[largest] 7. Heapify(A,largest) i l=10 1 12 3 2 7 10 6 5 4 3 2 4 Heapify(A,1)

More Related