LS 2 / Informatik Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)

95
LS 2 / Informatik Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)

Transcript of LS 2 / Informatik Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)

LS 2 / Informatik

Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)

LS 2 / Informatik

2

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)

Datenstrukturen

Universum UUniversum Uk

k

k kk

kk

k

1

2

3 4

5

6

7

8Genutzte Schlüsselmenge

nil

nil

nil

nil

nil

0

1

2

7

Feld T

h(k )=2

h(k )=5

h(k )=h(k )=6

6

3

4 8

k k109

LS 2 / Informatik

3

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)

Datenstrukturen

Universum UUniversum Uk

k

k kk

kk

k

1

2

3 4

5

6

7

8Genutzte Schlüsselmenge

nil

nil

nil

nil

nil

0

1

2

7

Feld T

h(k )=2

h(k )=5

h(k )=h(k )=6Kollision!

6

3

4 8

k k109

LS 2 / Informatik

4

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)

Datenstrukturen

Universum UUniversum Uk

k

k kk

kk

k

1

2

3 4

5

6

7

8Genutzte Schlüsselmenge

nil

nil

nil

nil

nil

0

1

2

7

Feld T

k

k

k k4 8

3

6k k

9 10

LS 2 / Informatik

5

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)]

Datenstrukturen

LS 2 / Informatik

6

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

Datenstrukturen

LS 2 / Informatik

7

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,yU gilt,dass die Anzahl der Funktion hH mit h(x)=h(y) genau |H|/t ist.

Anders gesagt: Wenn man x und y vorgibt und dann ein zufälliges hH 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

Datenstrukturen

LS 2 / Informatik

8

Satz 43 Sei MU 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.

Datenstrukturen

LS 2 / Informatik

9

Satz 43 Sei MU 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

Datenstrukturen

LS 2 / Informatik

10

Satz 43 Sei MU 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

Datenstrukturen

LS 2 / Informatik

11

Satz 43 Sei MU 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) = c(x,y)

Datenstrukturen

yM,yx

LS 2 / Informatik

12

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) = c(x,y)

Datenstrukturen

yM,yx

LS 2 / Informatik

13

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) = c(x,y)

Damit ist der durchschn. Wert E[C(x)] von C(x)

E[C(x)] = E[c(x,y)] ≤ n / t

Datenstrukturen

yM ,yx

yM,yx

LS 2 / Informatik

14

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) = c(x,y)

Damit ist der durchschn. Wert E[C(x)] von C(x)

E[C(x)] = E[c(x,y)] ≤ n / t

Da n≤t folgt E[C(x)] ≤ 1.

Datenstrukturen

yM ,yx

yM,yx

LS 2 / Informatik

15

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) = c(x,y)

Damit ist der durchschn. Wert E[C(x)] von C(x)

E[C(x)] = E[c(x,y)] ≤ n / t

Da n≤t folgt E[C(x)] ≤ 1.

Datenstrukturen

yM ,yx

yM,yx

LS 2 / Informatik

16

Konstruktion von H (ohne Beweis) Setze Tabellengröße t auf Primzahl

Datenstrukturen

LS 2 / Informatik

17

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

Datenstrukturen

0 1 r

0 1 r

LS 2 / Informatik

18

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}

Datenstrukturen

0 1 r

0 1 r

0 1 r

LS 2 / Informatik

19

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) = a ∙x mod t

Datenstrukturen

0 1 r

0 1 r

0 1 r

a

a i i

LS 2 / Informatik

20

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) = a ∙x mod t

Damit ist H die Vereinigung der h und |H| = t

Datenstrukturen

0 1 r

0 1 r

0 1 r

a

a i i

ar+1

LS 2 / Informatik

21

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) = a ∙x mod t

Damit ist H die Vereinigung der h und |H| = t Funktioniert bis Universumsgröße t

Datenstrukturen

0 1 r

0 1 r

0 1 r

a

a i i

ar+1

r+1

LS 2 / Informatik

22

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) = 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

Datenstrukturen

0 1 r

0 1 r

0 1 r

a

a i i

ar+1

r+1

LS 2 / Informatik

23

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) = 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

Datenstrukturen

0 1 r

0 1 r

0 1 r

a

a i i

ar+1

r+1

LS 2 / Informatik

24

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)

Datenstrukturen

LS 2 / Informatik

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

LS 2 / Informatik

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]

15 12 10 3 7 2

15

12 10

3 7 2

1 22 3

3 4

4 5

5 6

6

1

LS 2 / Informatik

27

Datenstrukturen

Navigation Wurzel ist A[1]

Parent(i)

1. return i/2

Left(i)1. return 2i

Right(i)1. return 2i+1

15 12 10 3 7 2

15

12 10

3 7 2

1

1 22 3

3 4

4 5

5 6

6

LS 2 / Informatik

28

Datenstrukturen

Navigation Wurzel ist A[1]

Parent(i)

1. return i/2

Left(i)1. return 2i

Right(i)1. return 2i+1

15 12 10 3 7 2

15

12 10

3 7 2

1

1 22 3

3 4

4 5

5 6

6

LS 2 / Informatik

29

Datenstrukturen

Navigation Wurzel ist A[1]

Parent(i)

1. return i/2

Left(i)1. return 2i

Right(i)1. return 2i+1

15 12 10 3 7 2

15

12 10

3 7 2

1

1 22 3

3 4

4 5

5 6

6

LS 2 / Informatik

30

Datenstrukturen

Navigation Wurzel ist A[1]

Parent(i)

1. return i/2

Left(i)1. return 2i

Right(i)1. return 2i+1

15 12 10 3 7 2

15

12 10

3 7 2

1

1 22 3

3 4

4 5

5 6

6

LS 2 / Informatik

31

Datenstrukturen

Navigation Wurzel ist A[1]

Parent(i)

1. return i/2

Left(i)1. return 2i

Right(i)1. return 2i+1

15 12 10 3 7 2

15

12 10

3 7 2

1

1 22 3

3 4

4 5

5 6

6

LS 2 / Informatik

32

Datenstrukturen

Navigation Wurzel ist A[1]

Parent(i)

1. return i/2

Left(i)1. return 2i

Right(i)1. return 2i+1

15 12 10 3 7 2

15

12 10

3 7 2

1

1 22 3

3 4

4 5

5 6

6

LS 2 / Informatik

33

Datenstrukturen

Haldeneigenschaft Für jeden Knoten i außer der Wurzel gilt A[Parent(i)]A[i]

15 12 10 3 7 2

15

12 10

3 7 2

1

1 22 3

3 4

4 5

5 6

6

LS 2 / Informatik

34

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

Datenstrukturen

HaldeHalde HaldeHalde

i

LS 2 / Informatik

35

Heapify(A,i)

1. l left(i)

2. r right(i)

3. if lheap-size[A] and A[l]>A[i] then largest l

4. else largest i

5. if rheap-size[A] and A[r]>A[largest] then largest r

6. if largesti then A[i] A[largest]

7. Heapify(A,largest)

Datenstrukturen

4 12 10 3 7 2

4

12 10

3 7 2

1

1 2

2 3

3 4

4 5

5 6

6

LS 2 / Informatik

36

Heapify(A,i)

1. l left(i)

2. r right(i)

3. if lheap-size[A] and A[l]>A[i] then largest l

4. else largest i

5. if rheap-size[A] and A[r]>A[largest] then largest r

6. if largesti then A[i] A[largest]

7. Heapify(A,largest)

Datenstrukturen

4 12 10 3 7 2

4

12 10

3 7 2

1

1 2

2 3

3 4

4 5

5 6

6

i

Heapify(A,1)

LS 2 / Informatik

37

Heapify(A,i)

1. l left(i)

2. r right(i)

3. if lheap-size[A] and A[l]>A[i] then largest l

4. else largest i

5. if rheap-size[A] and A[r]>A[largest] then largest r

6. if largesti then A[i] A[largest]

7. Heapify(A,largest)

Datenstrukturen

4 12 10 3 7 2

4

12 10

3 7 2

1

1 2

3

3 4

4 5

5 6

6

i

Heapify(A,1)

l=2

l

LS 2 / Informatik

38

Heapify(A,i)

1. l left(i)

2. r right(i)

3. if lheap-size[A] and A[l]>A[i] then largest l

4. else largest i

5. if rheap-size[A] and A[r]>A[largest] then largest r

6. if largesti then A[i] A[largest]

7. Heapify(A,largest)

Datenstrukturen

4 12 10 3 7 2

4

12 10

3 7 2

1

1 2 3 4

4 5

5 6

6

i

Heapify(A,1)

l=2

l r

r=3

LS 2 / Informatik

39

Heapify(A,i)

1. l left(i)

2. r right(i)

3. if lheap-size[A] and A[l]>A[i] then largest l

4. else largest i

5. if rheap-size[A] and A[r]>A[largest] then largest r

6. if largesti then A[i] A[largest]

7. Heapify(A,largest)

Datenstrukturen

4 12 10 3 7 2

4

12 10

3 7 2

1

1 2 3 4

4 5

5 6

6

i

Heapify(A,1)

l=2

l r

r=3

LS 2 / Informatik

40

Heapify(A,i)

1. l left(i)

2. r right(i)

3. if lheap-size[A] and A[l]>A[i] then largest l

4. else largest i

5. if rheap-size[A] and A[r]>A[largest] then largest r

6. if largesti then A[i] A[largest]

7. Heapify(A,largest)

Datenstrukturen

4 12 10 3 7 2

4

12 10

3 7 2

1

1 2 3 4

4 5

5 6

6

i

Heapify(A,1)

l=2

l r

r=3

LS 2 / Informatik

41

Heapify(A,i)

1. l left(i)

2. r right(i)

3. if lheap-size[A] and A[l]>A[i] then largest l

4. else largest i

5. if rheap-size[A] and A[r]>A[largest] then largest r

6. if largesti then A[i] A[largest]

7. Heapify(A,largest)

Datenstrukturen

12 4 10 3 7 2

12

4 10

3 7 2

1

1 2 3 4

4 5

5 6

6

Heapify(A,1)

2 3

i

LS 2 / Informatik

42

Heapify(A,i)

1. l left(i)

2. r right(i)

3. if lheap-size[A] and A[l]>A[i] then largest l

4. else largest i

5. if rheap-size[A] and A[r]>A[largest] then largest r

6. if largesti then A[i] A[largest]

7. Heapify(A,largest)

Datenstrukturen

12 4 10 3 7 2

12

4 10

3 7 2

1

1 2 3 4

5

5 6

6

Heapify(A,1)

2 3

l

l=4

i

LS 2 / Informatik

43

Heapify(A,i)

1. l left(i)

2. r right(i)

3. if lheap-size[A] and A[l]>A[i] then largest l

4. else largest i

5. if rheap-size[A] and A[r]>A[largest] then largest r

6. if largesti then A[i] A[largest]

7. Heapify(A,largest)

Datenstrukturen

12 4 10 3 7 2

12

4 10

3 7 2

1

1 2 3 4 5 6

6

Heapify(A,1)

2 3

l

l=4

r

r=5

i

LS 2 / Informatik

44

Heapify(A,i)

1. l left(i)

2. r right(i)

3. if lheap-size[A] and A[l]>A[i] then largest l

4. else largest i

5. if rheap-size[A] and A[r]>A[largest] then largest r

6. if largesti then A[i] A[largest]

7. Heapify(A,largest)

Datenstrukturen

12 4 10 3 7 2

12

4 10

3 7 2

1

1 2 3 4 5 6

6

Heapify(A,1)

2 3

l

l=4

r

r=5

i

LS 2 / Informatik

45

Heapify(A,i)

1. l left(i)

2. r right(i)

3. if lheap-size[A] and A[l]>A[i] then largest l

4. else largest i

5. if rheap-size[A] and A[r]>A[largest] then largest r

6. if largesti then A[i] A[largest]

7. Heapify(A,largest)

Datenstrukturen

12 4 10 3 7 2

12

4 10

3 7 2

1

1 2 3 4 5 6

6

Heapify(A,1)

2 3

l

l=4

r

r=5

i

LS 2 / Informatik

46

Heapify(A,i)

1. l left(i)

2. r right(i)

3. if lheap-size[A] and A[l]>A[i] then largest l

4. else largest i

5. if rheap-size[A] and A[r]>A[largest] then largest r

6. if largesti then A[i] A[largest]

7. Heapify(A,largest)

Datenstrukturen

12 4 10 3 7 2

12

4 10

3 7 2

1

1 2 3 4 5 6

6

Heapify(A,1)

2 3

l

l=4

r

r=5

i

LS 2 / Informatik

47

Heapify(A,i)

1. l left(i)

2. r right(i)

3. if lheap-size[A] and A[l]>A[i] then largest l

4. else largest i

5. if rheap-size[A] and A[r]>A[largest] then largest r

6. if largesti then A[i] A[largest]

7. Heapify(A,largest)

Datenstrukturen

12 7 10 3 4 2

12

7 10

3 4 2

1

1 2 3 4 5 6

6

Heapify(A,1)

2 3

l

l=4

r

r=5

i

LS 2 / Informatik

48

Heapify(A,i)

1. l left(i)

2. r right(i)

3. if lheap-size[A] and A[l]>A[i] then largest l

4. else largest i

5. if rheap-size[A] and A[r]>A[largest] then largest r

6. if largesti then A[i] A[largest]

7. Heapify(A,largest)

Datenstrukturen

12 7 10 3 4 2

12

7 10

3 4 2

1

1 2 3 4 5 6

6

i

Heapify(A,1)

2 3

l

l=4

r

r=5

LS 2 / Informatik

49

Heapify(A,i)

1. l left(i)

2. r right(i)

3. if lheap-size[A] and A[l]>A[i] then largest l

4. else largest i

5. if rheap-size[A] and A[r]>A[largest] then largest r

6. if largesti then A[i] A[largest]

7. Heapify(A,largest)

Datenstrukturen

12 7 10 3 4 2

12

7 10

3 4 2

1

1 2 3 4 5 6

6

Heapify(A,1)

2 3

4 5

i

LS 2 / Informatik

50

Heapify(A,i)

1. l left(i)

2. r right(i)

3. if lheap-size[A] and A[l]>A[i] then largest l

4. else largest i

5. if rheap-size[A] and A[r]>A[largest] then largest r

6. if largesti then A[i] A[largest]

7. Heapify(A,largest)

Datenstrukturen

12 7 10 3 4 2

12

7 10

3 4 2

1

1 2 3 4 5 6

6

Heapify(A,1)

2 3

4 5

il=10

LS 2 / Informatik

51

Heapify(A,i)

1. l left(i)

2. r right(i)

3. if lheap-size[A] and A[l]>A[i] then largest l

4. else largest i

5. if rheap-size[A] and A[r]>A[largest] then largest r

6. if largesti then A[i] A[largest]

7. Heapify(A,largest)

Datenstrukturen

12 7 10 3 4 2

12

7 10

3 4 2

1

1 2 3 4 5 6

6

Heapify(A,1)

2 3

4 5

il=10

r=11

LS 2 / Informatik

52

Heapify(A,i)

1. l left(i)

2. r right(i)

3. if lheap-size[A] and A[l]>A[i] then largest l

4. else largest i

5. if rheap-size[A] and A[r]>A[largest] then largest r

6. if largesti then A[i] A[largest]

7. Heapify(A,largest)

Datenstrukturen

12 7 10 3 4 2

12

7 10

3 4 2

1

1 2 3 4 5 6

6

Heapify(A,1)

2 3

4 5

il=10

r=11

LS 2 / Informatik

53

Heapify(A,i)

1. l left(i)

2. r right(i)

3. if lheap-size[A] and A[l]>A[i] then largest l

4. else largest i

5. if rheap-size[A] and A[r]>A[largest] then largest r

6. if largesti then A[i] A[largest]

7. Heapify(A,largest)

Datenstrukturen

12 7 10 3 4 2

12

7 10

3 4 2

1

1 2 3 4 5 6

6

Heapify(A,1)

2 3

4 5

il=10

r=11

LS 2 / Informatik

54

Heapify(A,i)

1. l left(i)

2. r right(i)

3. if lheap-size[A] and A[l]>A[i] then largest l

4. else largest i

5. if rheap-size[A] and A[r]>A[largest] then largest r

6. if largesti then A[i] A[largest]

7. Heapify(A,largest)

Datenstrukturen

12 7 10 3 4 2

12

7 10

3 4 2

1

1 2 3 4 5 6

6

Heapify(A,1)

2 3

4 5

il=10

r=11

LS 2 / Informatik

55

Heapify(A,i)

1. l left(i)

2. r right(i)

3. if lheap-size[A] and A[l]>A[i] then largest l

4. else largest i

5. if rheap-size[A] and A[r]>A[largest] then largest r

6. if largesti then A[i] A[largest]

7. Heapify(A,largest)

Datenstrukturen

12 7 10 3 4 2

12

7 10

3 4 2

1

1 2 3 4 5 6

6

Heapify(A,1)

2 3

4 5

il=10

r=11

LS 2 / Informatik

56

Heapify(A,i)

1. l left(i)

2. r right(i)

3. if lheap-size[A] and A[l]>A[i] then largest l

4. else largest i

5. if rheap-size[A] and A[r]>A[largest] then largest r

6. if largesti then A[i] A[largest]

7. Heapify(A,largest)

Datenstrukturen

12 7 10 3 4 2

12

7 10

3 4 2

1

1 2 3 4 5 6

6

Heapify(A,1)

2 3

4 5

LS 2 / Informatik

57

Definition Die Höhe eines Knotens v in einem Baum ist die Höhe des Unterbaums von v;

Beispiel

Datenstrukturen

12

7 10

3 4 2

Höhe des Knotens ist 1

LS 2 / Informatik

58

Satz 44 Die Laufzeit von Heapify(A,i) ist O(h), wobei h die Höhe des zu i zugehörigen

Knotens in der Baumdarstellung des Heaps ist.

Beweis Zeige per Induktion über h, das die Laufzeit ≤c∙h ist

(für c hinreichend große Konstante) (I.A.) Ist h=0, so wird in Zeile 4 largest auf i gesetzt. In Zeile 5 wird dieser Wert nicht verändert.

Daher wird in Zeile 6 kein rekursiver Aufruf durchgeführt und die Laufzeit ist c. (I.V.) Für Knoten der Höhe h ist die Laufzeit ch.

Datenstrukturen

LS 2 / Informatik

59

Satz 44 Die Laufzeit von Heapify(A,i) ist O(h), wobei h die Höhe des zu i zugehörigen

Knotens in der Baumdarstellung des Heaps ist.

Beweis (I.V.) Für Knoten der Höhe h ist die Laufzeit ch. (I.S.) Betrachte einen Knoten der Höhe h+1. In Zeile 3-5 wird largest entweder auf i oder auf den Wert

eines der Kinder von i gesetzt. Wird nun in Zeile 6 ein rekursiver Aufruf durchgeführt, so geschieht dies mit einem der Kinderknoten. Diese haben Höhe h und daher hat der rekursive Aufruf nach (I.V.) eine Laufzeit von ch. Die übrige Laufzeit ist durch c beschränkt.Damit ergibt sich eine Laufzeit von maximal ch+c = c(h+1).

Datenstrukturen

LS 2 / Informatik

60

Satz 45 Wenn die Unterbäume des rechten bzw. linken Kindes von i die

Haldeneigenschaft besitzen, dann ist diese nach der Operation Heapify(A,i) für den Unterbaum von i erfüllt.

Datenstrukturen

HaldeHalde HaldeHalde

i

LS 2 / Informatik

61

Satz 45 Wenn die Unterbäume des rechten bzw. linken Kindes von i die Haldeneigenschaft besitzen,

dann ist diese nach der Operation Heapify(A,i) für den Unterbaum von i erfüllt.

Beweis Induktion über die Höhe von i. (I.A.) Hat i Höhe 0 oder 1, so kann man einfach nachprüfen, dass Heapify die Aussage des

Satzes erfüllt. (I.V.) Heapify erfüllt die Aussage des Satzes für Knoten i mit Höhe h.

Datenstrukturen

LS 2 / Informatik

62

Satz 45 Wenn die Unterbäume des rechten bzw. linken Kindes von i die Haldeneigenschaft besitzen, dann ist diese nach

der Operation Heapify(A,i) für den Unterbaum von i erfüllt.

Beweis (I.S.) Betrachte Aufruf Heapify(A,i) für einen Knoten i der Höhe h+1>1 und wenn die Unterbäume des rechten bzw.

linken Kindes von i bereits die Haldeneigenschaft erfüllen. Es seien l und r das linke bzw. rechte Kind von i. Da die Höhe von i größer 1 ist, sind l und r kleiner als heap-size[A] sind die an l und r gespeicherten Werte in der Halde. Es seien A[i], A[l] und A[r] die Werte, die an den entsprechenden Knoten gespeichert wurden. Heapify(A,i) speichert in Zeilen 3-5 den Index des Maximums von A[i], A[l] und A[r] in der Variable largest. Ist das Maximum A[i], so ist die Haldeneigenschaft bereits erfüllt, da die Unterbäume von l und r bereits Halden sind.

Datenstrukturen

LS 2 / Informatik

63

Satz 45 Wenn die Unterbäume des rechten bzw. linken Kindes von i die Haldeneigenschaft besitzen, dann ist

diese nach der Operation Heapify(A,i) für den Unterbaum von i erfüllt.

Beweis Es bleibt der Fall, dass A[i] nicht das Maximum ist. Wir betrachten den Fall, dass das Maximum in A[l]

ist. Der andere Fall ist analog. Da die Unterbäume von l und r Halden sind, sind A[l] und A[r] die größten Elemente, die in den jeweiligen Unterbäumen gespeichert sind. Da A[l] das Maximum von A[i], A[l] und A[r] ist, ist es das größte Element im Unterbaum von i. In Zeile 6 wird nun A[i] mit A[l] getauscht und in Zeile 7 wird rekursiv Heapify für den Unterbaum des linken Kindes von l aufgerufen.

Datenstrukturen

LS 2 / Informatik

64

Satz 45 Wenn die Unterbäume des rechten bzw. linken Kindes von i die Haldeneigenschaft besitzen, dann ist

diese nach der Operation Heapify(A,i) für den Unterbaum von i erfüllt.

Beweis In Zeile 6 wird nun A[i] mit A[l] getauscht und in Zeile 7 wird rekursiv Heapify für den Unterbaum des

linken Kindes von i aufgerufen. Dieses hat Höhe h und die Unterbäume seiner Kinder besitzen die Haldeneigenschaft. Somit besitzt der Unterbaum von l nach (I.V.) nach dem Aufruf von Heapify ebenfalls die Halden-eigenschaft. Da an Knoten i nun das Maximum aller Elemente im Unterbaum von i gespeichert ist und der rechte Unterbaum ebenfalls die Haldeneigenschaft erfüllt, ist der Unterbaum von i eine Halde.

Datenstrukturen

LS 2 / Informatik

65

Aufbau einer Halde Jedes Blatt ist eine Halde Baue Halde „von unten nach oben“ mit Heapify auf

Build-Heap(A)

1. heap-size length[A]

2. for i length[A]/2 downto 1 do

3. Heapify(A,i)

Datenstrukturen

LS 2 / Informatik

66

Aufbau einer Halde Jedes Blatt ist eine Halde Baue Halde „von unten nach oben“ mit Heapify auf

Build-Heap(A)

1. heap-size length[A]

2. for i length[A]/2 downto 1 do

3. Heapify(A,i)

Datenstrukturen 3 7 10 12 2 4

3

7 10

12 2 4

1

2 3

4 5 6

1 2 3 4 5 6

LS 2 / Informatik

67

Aufbau einer Halde Jedes Blatt ist eine Halde Baue Halde „von unten nach oben“ mit Heapify auf

Build-Heap(A)

1. heap-size length[A]

2. for i length[A]/2 downto 1 do

3. Heapify(A,i)

Datenstrukturen 3 7 10 12 2 4

3

7 10

12 2 4

1

2 3

4 5 6

1 2 3 4 5 6

LS 2 / Informatik

68

Aufbau einer Halde Jedes Blatt ist eine Halde Baue Halde „von unten nach oben“ mit Heapify auf

Build-Heap(A)

1. heap-size length[A]

2. for i length[A]/2 downto 1 do

3. Heapify(A,i)

Datenstrukturen 3 7 10 12 2 4

3

7 10

12 2 4

1

2 3

4 5 6

1 2 3 4 5 6

i

LS 2 / Informatik

69

Aufbau einer Halde Jedes Blatt ist eine Halde Baue Halde „von unten nach oben“ mit Heapify auf

Build-Heap(A)

1. heap-size length[A]

2. for i length[A]/2 downto 1 do

3. Heapify(A,i)

Datenstrukturen 3 7 10 12 2 4

3

7 10

12 2 4

1

2 3

4 5 6

1 2 3 4 5 6

i

LS 2 / Informatik

70

Aufbau einer Halde Jedes Blatt ist eine Halde Baue Halde „von unten nach oben“ mit Heapify auf

Build-Heap(A)

1. heap-size length[A]

2. for i length[A]/2 downto 1 do

3. Heapify(A,i)

Datenstrukturen 3 7 10 12 2 4

3

7 10

12 2 4

1

2 3

4 5 6

1 2 3 4 5 6

i

LS 2 / Informatik

71

Aufbau einer Halde Jedes Blatt ist eine Halde Baue Halde „von unten nach oben“ mit Heapify auf

Build-Heap(A)

1. heap-size length[A]

2. for i length[A]/2 downto 1 do

3. Heapify(A,i)

Datenstrukturen 3 12 10 7 2 4

3

12 10

7 2 4

1

2 3

4 5 6

1 2 3 4 5 6

i

LS 2 / Informatik

72

Aufbau einer Halde Jedes Blatt ist eine Halde Baue Halde „von unten nach oben“ mit Heapify auf

Build-Heap(A)

1. heap-size length[A]

2. for i length[A]/2 downto 1 do

3. Heapify(A,i)

Datenstrukturen 3 12 10 7 2 4

3

12 10

7 2 4

1

2 3

4 5 6

1 2 3 4 5 6

i

LS 2 / Informatik

73

Aufbau einer Halde Jedes Blatt ist eine Halde Baue Halde „von unten nach oben“ mit Heapify auf

Build-Heap(A)

1. heap-size length[A]

2. for i length[A]/2 downto 1 do

3. Heapify(A,i)

Datenstrukturen 12 7 10 3 2 4

12

7 10

3 2 4

1

2 3

4 5 6

1 2 3 4 5 6

i

LS 2 / Informatik

74

Aufbau einer Halde Jedes Blatt ist eine Halde Baue Halde „von unten nach oben“ mit Heapify auf

Build-Heap(A)

1. heap-size length[A]

2. for i length[A]/2 downto 1 do

3. Heapify(A,i)

Datenstrukturen 12 7 10 3 2 4

12

7 10

3 2 4

1

2 3

4 5 6

1 2 3 4 5 6

i

LS 2 / Informatik

75

Satz 46 Mit Hilfe des Algorithmus Build-Heap kann man eine Halde in O(n) Zeit aufbauen.

Beweis Wir zeigen zunächst die Korrektheit. In der for-Schleife gilt die Invariante,

dass die Unterbäume der Knoten größer als i bereits die Haldeneigenschaft besitzen. Dies gilt insbesondere für die Unterbäume der Kinder von i. Aus unserem vorherigen Satz folgt, dass die Invariante durch Heapify aufrechterhalten wird. Damit gilt am Ende der Schleife die Haldeneigenschaft für die Wurzel und somit erzeugt Build-Heap eine Halde.

Datenstrukturen

LS 2 / Informatik

76

Satz 46 Mit Hilfe des Algorithmus Build-Heap kann man eine Halde in O(n) Zeit aufbauen.

Beweis Einfache Laufzeitanalyse: Jedes Heapify benötigt O(h) = O(log n) Laufzeit.

Da es insgesamt O(n) Heapify Operationen gibt, ist die Laufzeit O(n log n).

Datenstrukturen

LS 2 / Informatik

77

Satz 46 Mit Hilfe des Algorithmus Build-Heap kann man eine Halde in O(n) Zeit aufbauen.

Beweis Schärfere Laufzeitanalyse: Beobachtung: In einer Halde mit Höhe H gibt es maximal 2 Knoten mit

Höhe H, 2 Knoten mit Höhe H-1, 2 Knoten mit Höhe H-2, usw.

Damit ergibt sich als Gesamtlaufzeit bei n Knoten und Höhe H=log n:

Datenstrukturen

H

hh

H

hh

HH

h

hH hnO

hOhOHHO

000

10

2222...)2)1(2(

0

1 2

LS 2 / Informatik

78

Satz 46 Mit Hilfe des Algorithmus Build-Heap kann man eine Halde in O(n) Zeit aufbauen.

Beweis

Es gilt

Somit folgt eine Laufzeit von O(n).

Datenstrukturen

H

hh

H

hh

HH

h

hH hnO

hOhOHHO

000

10

2222...)2)1(2(

)1(20

Oh

hh

LS 2 / Informatik

79

Heap-Extract-Max(A)

1. if heap-size[A] < 1 then error „Kein Element vorhanden!“

2. max A[1]

3. A[1] A[heap-size[A]]

4. heap-size[A] heap-size[A]-1

5. Heapify(A,1)

6. return max

Datenstrukturen

12 7 10 3 2 4

12

7 10

3 2 4

1

2 3

4 5 6

1 2 3 4 5 6

LS 2 / Informatik

80

Heap-Extract-Max(A)

1. if heap-size[A] < 1 then error „Kein Element vorhanden!“

2. max A[1]

3. A[1] A[heap-size[A]]

4. heap-size[A] heap-size[A]-1

5. Heapify(A,1)

6. return max

Datenstrukturen

12 7 10 3 2 4

12

7 10

3 2 4

1

2 3

4 5 6

1 2 3 4 5 6

LS 2 / Informatik

81

Heap-Extract-Max(A)

1. if heap-size[A] < 1 then error „Kein Element vorhanden!“

2. max A[1]

3. A[1] A[heap-size[A]]

4. heap-size[A] heap-size[A]-1

5. Heapify(A,1)

6. return max

Datenstrukturen

12 7 10 3 2 4

12

7 10

3 2 4

1

2 3

4 5 6

1 2 3 4 5 6

max =12

LS 2 / Informatik

82

Heap-Extract-Max(A)

1. if heap-size[A] < 1 then error „Kein Element vorhanden!“

2. max A[1]

3. A[1] A[heap-size[A]]

4. heap-size[A] heap-size[A]-1

5. Heapify(A,1)

6. return max

Datenstrukturen

4 7 10 3 2 4

4

7 10

3 2 4

1

2 3

4 5 6

1 2 3 4 5 6

max =12

LS 2 / Informatik

83

Heap-Extract-Max(A)

1. if heap-size[A] < 1 then error „Kein Element vorhanden!“

2. max A[1]

3. A[1] A[heap-size[A]]

4. heap-size[A] heap-size[A]-1

5. Heapify(A,1)

6. return max

Datenstrukturen

4 7 10 3 2 4

4

7 10

3 2

1

2 3

4 5

1 2 3 4 5 6

max =12

LS 2 / Informatik

84

Heap-Extract-Max(A)

1. if heap-size[A] < 1 then error „Kein Element vorhanden!“

2. max A[1]

3. A[1] A[heap-size[A]]

4. heap-size[A] heap-size[A]-1

5. Heapify(A,1)

6. return max

Datenstrukturen

10 7 4 3 2 4

10

7 4

3 2

1

2 3

4 5

1 2 3 4 5 6

max =12

LS 2 / Informatik

85

Heap-Extract-Max(A)

1. if heap-size[A] < 1 then error „Kein Element vorhanden!“

2. max A[1]

3. A[1] A[heap-size[A]]

4. heap-size[A] heap-size[A]-1

5. Heapify(A,1)

6. return max

Datenstrukturen

10 7 4 3 2 4

10

7 4

3 2

1

2 3

4 5

1 2 3 4 5 6

max =12

LS 2 / Informatik

86

Heap-Extract-Max(A)

1. if heap-size[A] < 1 then error „Kein Element vorhanden!“

2. max A[1]

3. A[1] A[heap-size[A]]

4. heap-size[A] heap-size[A]-1

5. Heapify(A,1)

6. return max

Laufzeit• O(log n)

Datenstrukturen

10 7 4 3 2 4

10

7 4

3 2

1

2 3

4 5

1 2 3 4 5 6

LS 2 / Informatik

87

Heap-Insert(A,key)

1. heap-size[A] heap-size[A]+1

2. i heap-size[A]

3. while i>1 and A[Parent(i)] < key do

4. A[i] A[Parent(i)]

5. i Parent(i)

6. A[i] key

Datenstrukturen

10 7 4 3 2 4

10

7 4

3 2

1

2 3

4 5

1 2 3 4 5 6

LS 2 / Informatik

88

Heap-Insert(A,key)

1. heap-size[A] heap-size[A]+1

2. i heap-size[A]

3. while i>1 and A[Parent(i)] < key do

4. A[i] A[Parent(i)]

5. i Parent(i)

6. A[i] key

Datenstrukturen

10 7 4 3 2 4

10

7 4

3 2

1

2 3

4 5

1 2 3 4 5 6

Heap-Insert(A,11)

6

4

LS 2 / Informatik

89

Heap-Insert(A,key)

1. heap-size[A] heap-size[A]+1

2. i heap-size[A]

3. while i>1 and A[Parent(i)] < key do

4. A[i] A[Parent(i)]

5. i Parent(i)

6. A[i] key

Datenstrukturen

10 7 4 3 2 4

10

7 4

3 2

1

2 3

4 5

1 2 3 4 5 6

Heap-Insert(A,11)

4

6

i

LS 2 / Informatik

90

Heap-Insert(A,key)

1. heap-size[A] heap-size[A]+1

2. i heap-size[A]

3. while i>1 and A[Parent(i)] < key do

4. A[i] A[Parent(i)]

5. i Parent(i)

6. A[i] key

Datenstrukturen

10 7 4 3 2 4

10

7 4

3 2

1

2 3

4 5

1 2 3 4 5 6

Heap-Insert(A,11)

4

6

i

LS 2 / Informatik

91

Heap-Insert(A,key)

1. heap-size[A] heap-size[A]+1

2. i heap-size[A]

3. while i>1 and A[Parent(i)] < key do

4. A[i] A[Parent(i)]

5. i Parent(i)

6. A[i] key

Datenstrukturen

10 7 4 3 2 4

10

7 4

3 2

1

2 3

4 5

1 2 3 4 5 6

Heap-Insert(A,11)

4

6

i

LS 2 / Informatik

92

Heap-Insert(A,key)

1. heap-size[A] heap-size[A]+1

2. i heap-size[A]

3. while i>1 and A[Parent(i)] < key do

4. A[i] A[Parent(i)]

5. i Parent(i)

6. A[i] key

Datenstrukturen

10 7 4 3 2 4

10

7 4

3 2

1

2 3

4 5

1 2 3 4 5 6

Heap-Insert(A,11)

4

6

i

LS 2 / Informatik

93

Heap-Insert(A,key)

1. heap-size[A] heap-size[A]+1

2. i heap-size[A]

3. while i>1 and A[Parent(i)] < key do

4. A[i] A[Parent(i)]

5. i Parent(i)

6. A[i] key

Datenstrukturen

10 7 10 3 2 4

10

7 10

3 2

1

2 3

4 5

1 2 3 4 5 6

Heap-Insert(A,11)

4

6

i

LS 2 / Informatik

94

Heap-Insert(A,key)

1. heap-size[A] heap-size[A]+1

2. i heap-size[A]

3. while i>1 and A[Parent(i)] < key do

4. A[i] A[Parent(i)]

5. i Parent(i)

6. A[i] key

Datenstrukturen

10 7 10 3 2 4

10

7 10

3 2

1

2 3

4 5

1 2 3 4 5 6

Heap-Insert(A,11)

4

6

i

LS 2 / Informatik

95

Heap-Insert(A,key)

1. heap-size[A] heap-size[A]+1

2. i heap-size[A]

3. while i>1 and A[Parent(i)] < key do

4. A[i] A[Parent(i)]

5. i Parent(i)

6. A[i] key

Laufzeit• O(log n)

Datenstrukturen

11 7 10 3 2 4

11

7 10

3 2

1

2 3

4 5

1 2 3 4 5 6

4

6