Präsentation herunterladen
Die Präsentation wird geladen. Bitte warten
Veröffentlicht von:Lothar Langel Geändert vor über 10 Jahren
1
Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)
2
Organisatorisches Übungen Lernraumbetreuung Zweiter Test
Ab der nächsten Heimübung ist die Teilnahme an der Besprechung der Heimübung nicht mehr verpflichtend Lernraumbetreuung Mo 14:30-17:30 in U04 zur C-Betreuung (Praktikum) Dafür fällt aus: Mo 14:30 – 17:30 Zweiter Test Aufgabe 1: Nachvollziehen eines Algorithmus oder einer Datenstruktur Aufgabe 2: Entwurf und Analyse eines Algorithmus zur dynamischen Programmierung Aufgabe 3: Entwurf und Analyse eines gierigen Algorithmus
3
Datenstrukturen Datenstruktur Feld Vorteile Nachteile
Platzbedarf Q(max) Laufzeit Suche: Q(n) Laufzeit Einfügen/Löschen: Q(1) Vorteile Schnelles Einfügen und Löschen Nachteile Speicherbedarf abhängig von max (nicht vorhersagbar) Hohe Laufzeit für Suche
4
Datenstrukturen Datenstruktur „sortiertes Feld“ A
Sortiertes Feld A[1,…,max] Integer n, 1 n max n bezeichnet Anzahl Elemente in Datenstruktur 2 4 6 7 11 13 nil A n
5
Datenstrukturen Einfügen(s) n n+1 i n while s < A[i-1] do
A[i] A[i-1] i i -1 A[i] s 2 4 6 7 11 13 nil n Einfügen(10)
6
Datenstrukturen Einfügen(s) n n+1 i n while s < A[i-1] do
A[i] A[i-1] i i -1 A[i] s 2 4 6 7 11 13 nil n Einfügen(10)
7
Datenstrukturen Einfügen(s) n n+1 i n while s < A[i-1] do
A[i] A[i-1] i i -1 A[i] s 2 4 6 7 11 13 nil n Einfügen(10)
8
Datenstrukturen Einfügen(s) n n+1 i n while s < A[i-1] do
A[i] A[i-1] i i -1 A[i] s 2 4 6 7 11 13 nil n Einfügen(10)
9
Datenstrukturen Einfügen(s) n n+1 i n while s < A[i-1] do
A[i] A[i-1] i i -1 A[i] s Laufzeit O(n) 2 4 6 7 10 11 13 nil n Einfügen(10)
10
Datenstrukturen Löschen(i)
Parameter ist der Index des zu löschenden Objekts Löschen(i) for j i to n-1 do A[j] A[j+1] A[n] nil n n-1 2 4 6 7 11 13 nil n
11
Datenstrukturen Löschen(i)
Parameter ist der Index des zu löschenden Objekts Löschen(i) for j i to n-1 do A[j] A[j+1] A[n] nil n n-1 2 4 6 7 11 13 nil n Löschen(2)
12
Datenstrukturen Löschen(i)
Parameter ist der Index des zu löschenden Objekts Löschen(i) for j i to n-1 do A[j] A[j+1] A[n] nil n n-1 i 2 4 6 7 11 13 nil n Löschen(2)
13
Datenstrukturen Löschen(i) for j i to n-1 do A[j] A[j+1]
A[n] nil n n-1 i 2 4 6 7 11 13 nil n Löschen(2)
14
Datenstrukturen Löschen(i) for j i to n-1 do A[j] A[j+1]
A[n] nil n n-1 i 2 6 7 11 13 nil n Löschen(2)
15
Datenstrukturen Löschen(i) for j i to n-1 do A[j] A[j+1]
A[n] nil n n-1 i 2 6 7 11 13 nil n Löschen(2)
16
Datenstrukturen Löschen(i) for j i to n-1 do A[j] A[j+1]
A[n] nil n n-1 i 2 6 7 11 13 nil n Löschen(2)
17
Datenstrukturen Suchen(x) Binäre Suche Laufzeit O(log n) i 2 6 7 11 13
nil n Löschen(2)
18
Datenstrukturen Datenstruktur sortiertes Feld Vorteile Nachteile
Platzbedarf Q(max) Laufzeit Suche: Q(log n) Laufzeit Einfügen/Löschen: Q(n) Vorteile Schnelles Suchen Nachteile Speicherbedarf abhängig von max (nicht vorhersagbar) Hohe Laufzeit für Einfügen/Löschen
19
nil 5 7 4 nil Datenstrukturen Doppelt verkettete Listen
Listenelement x ist Objekt bestehend aus Schlüssel und zwei Zeigern prev und next next verweist auf Nachfolger von x prev verweist auf Vorgänger von x prev/next sind nil, wenn Vorgänger/Nachfolger nicht existiert head[L] zeigt auf das erste Element prev next nil 5 7 4 nil head[L] Schlüssel
20
nil 7 4 nil Datenstrukturen Einfügen(L,x) next[x] head[L]
if head[L] nil then prev[head[L]] x head[L] x prev[x] nil nil 7 4 nil head[L]
21
x 5 nil 7 4 nil Datenstrukturen Einfügen(L,x) next[x] head[L]
if head[L] nil then prev[head[L]] x head[L] x prev[x] nil x 5 nil 7 4 nil head[L]
22
x 5 7 4 nil Datenstrukturen Einfügen(L,x) next[x] head[L]
if head[L] nil then prev[head[L]] x head[L] x prev[x] nil x 5 7 4 nil head[L]
23
x 5 7 4 nil Datenstrukturen Einfügen(L,x) next[x] head[L]
if head[L] nil then prev[head[L]] x head[L] x prev[x] nil x 5 7 4 nil head[L]
24
x nil 5 7 4 nil Datenstrukturen Einfügen(L,x) next[x] head[L]
if head[L] nil then prev[head[L]] x head[L] x prev[x] nil x nil 5 7 4 nil head[L]
25
x nil 5 7 4 nil Datenstrukturen Laufzeit Einfügen(L,x)
next[x] head[L] if head[L] nil then prev[head[L]] x head[L] x prev[x] nil Laufzeit O(1) x nil 5 7 4 nil head[L]
26
nil 5 7 4 nil Datenstrukturen Löschen(L,x)
if prev[x] nil then next[prev[x]] next[x] else head[L] next[x] if next[x] nil then prev[next[x]] prev[x] delete x nil 5 7 4 nil head[L]
27
x nil 5 7 4 nil Datenstrukturen Löschen(L,x)
if prev[x] nil then next[prev[x]] next[x] else head[L] next[x] if next[x] nil then prev[next[x]] prev[x] delete x x nil 5 7 4 nil head[L]
28
nil 5 x 4 nil 7 Datenstrukturen Löschen(L,x)
if prev[x] nil then next[prev[x]] next[x] else head[L] next[x] if next[x] nil then prev[next[x]] prev[x] delete x nil 5 x 4 nil head[L] 7
29
nil 5 4 nil 7 x Datenstrukturen Löschen(L,x)
if prev[x] nil then next[prev[x]] next[x] else head[L] next[x] if next[x] nil then prev[next[x]] prev[x] delete x nil 5 4 nil head[L] 7 x
30
nil 5 4 nil Datenstrukturen Löschen(L,x)
if prev[x] nil then next[prev[x]] next[x] else head[L] next[x] if next[x] nil then prev[next[x]] prev[x] delete x nil 5 4 nil head[L]
31
nil 5 4 nil Datenstrukturen Laufzeit Löschen(L,x)
if prev[x] nil then next[prev[x]] next[x] else head[L] next[x] if next[x] nil then prev[next[x]] prev[x] delete x Laufzeit O(1) nil 5 4 nil head[L]
32
Datenstrukturen Suche(L,k) x head[L] while xnil and key[x]k do
x next[x] return x
33
nil 5 4 nil Datenstrukturen Suche(L,k) x head[L]
while xnil and key[x]k do x next[x] return x nil 5 4 nil head[L]
34
x nil 5 4 nil Suche(L,4) Datenstrukturen Suche(L,k) x head[L]
while xnil and key[x]k do x next[x] return x x nil 5 4 nil head[L] Suche(L,4)
35
nil 5 4 nil Suche(L,4) Datenstrukturen Suche(L,k) x head[L]
while xnil and key[x]k do x next[x] return x nil 5 4 nil head[L] Suche(L,4)
36
x nil 5 4 nil Suche(L,4) Datenstrukturen Suche(L,k) x head[L]
while xnil and key[x]k do x next[x] return x x nil 5 4 nil head[L] Suche(L,4)
37
x nil 5 4 nil Suche(L,4) Datenstrukturen Suche(L,k) x head[L]
while xnil and key[x]k do x next[x] return x x nil 5 4 nil head[L] Suche(L,4)
38
x nil 5 4 nil Suche(L,4) Datenstrukturen Suche(L,k) x head[L]
while xnil and key[x]k do x next[x] return x x nil 5 4 nil head[L] Suche(L,4)
39
x nil 5 4 nil Suche(L,4) Datenstrukturen Laufzeit Suche(L,k)
x head[L] while xnil and key[x]k do x next[x] return x Laufzeit O(n) x nil 5 4 nil head[L] Suche(L,4)
40
Datenstrukturen Datenstruktur Liste: Vorteile Nachteile
Platzbedarf Q(n) Laufzeit Suche: Q(n) Laufzeit Einfügen/Löschen: Q(1) Vorteile Schnelles Einfügen/Löschen O(n) Speicherbedarf Nachteile Hohe Laufzeit für Suche
41
Datenstrukturen Drei grundlegende Datenstrukturen Diskussion Feld
sortiertes Feld doppelt verkettete Liste Diskussion Alle drei Strukturen haben gewichtige Nachteile Zeiger/Referenzen helfen beim Speichermanagement Sortierung hilft bei Suche ist aber teuer aufrecht zu erhalten
42
Datenstrukturen Binärbäume key p[v] lc[v] rc[v] / / / / /
Schlüssel key und ggf. weitere Daten Vaterzeiger p[v] auf Vater von v (blau) Zeiger lc[v] (rc[v]) auf linkes (rechtes) Kind von v Wurzelzeiger root[T] key p[v] lc[v] rc[v] root[T] / / / / /
43
Datenstrukturen Binäre Suchbäume Binäre Suchbaumeigenschaft: 6
Verwende Binärbaum Speichere Schlüssel „geordnet“ Binäre Suchbaumeigenschaft: Sei x Knoten im binären Suchbaum Ist y Knoten im linken Unterbaum von x, dann gilt key[y]key[x] Ist y Knoten im rechten Unterbaum von x, dann gilt key[y]>key[x] 6 4 7 3 7 9
44
Datenstrukturen Unterschiedliche Suchbäume Schlüsselmenge 3,4,6,7,7,9
Wir erlauben mehrfache Vorkommen desselben Schlüssels 3 6 6 4 7 7 3 4 7 9 7 9
45
6 4 7 3 9 7 Datenstrukturen Ausgabe aller Schlüssel
Gegeben binärer Suchbaum Wie kann man alle Schlüssel aufsteigend sortiert in Q(n) Zeit ausgeben? 6 4 7 3 9 7
46
6 4 7 3 9 7 Datenstrukturen Inorder-Tree-Walk(x)
Aufruf über Inorder-Tree-Walk(root[T]) Inorder-Tree-Walk(x) 1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) 6 4 7 3 9 7
47
6 4 7 3 9 7 Datenstrukturen Inorder-Tree-Walk(x) 1. if xnil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) 6 4 7 3 9 7
48
6 4 7 3 9 7 Datenstrukturen Inorder-Tree-Walk(x) 1. if xnil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) 6 4 7 3 9 7
49
6 4 7 3 9 7 Datenstrukturen Inorder-Tree-Walk(x) 1. if xnil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) 6 4 7 3 9 7
50
6 4 7 3 9 7 Datenstrukturen Inorder-Tree-Walk(x) 1. if xnil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) 6 4 7 3 9 7
51
6 4 7 3 9 7 Datenstrukturen Inorder-Tree-Walk(x) 1. if xnil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) 6 4 7 3 9 7
52
6 4 7 x x 3 9 7 nil Datenstrukturen Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) 6 Kein linkes Kind vorhanden, d.h. lc[x]=nil 4 7 x x 3 9 7 nil
53
6 4 7 x x 3 9 7 nil Datenstrukturen Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) 6 Kein linkes Kind vorhanden, d.h. lc[x]=nil 4 7 x x 3 9 7 nil
54
6 4 7 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3 6 4 7 3 9 7
55
6 4 7 3 9 7 nil Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3 6 Kein rechtes Kind vorhanden, d.h. rc[x]=nil 4 7 3 9 7 nil
56
6 4 7 3 9 7 nil Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3 6 Kein rechtes Kind vorhanden, d.h. rc[x]=nil 4 7 3 9 7 nil
57
6 4 7 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3 6 Knoten abgearbeitet 4 7 3 9 7
58
6 4 7 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4 6 4 7 3 9 7
59
6 4 7 nil 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4 6 4 7 nil 3 9 7
60
6 4 7 nil 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4 6 4 7 nil 3 9 7
61
6 4 7 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4 6 4 7 3 9 7
62
6 4 7 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4, 6 6 4 7 3 9 7
63
6 4 7 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4, 6 6 4 7 3 9 7
64
6 4 7 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4, 6 6 4 7 3 9 7
65
6 4 7 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4, 6 6 4 7 3 9 7
66
6 4 7 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4, 6 6 4 7 3 9 7
67
6 4 7 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4, 6 6 4 7 3 9 7
68
6 4 7 3 9 7 nil Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4, 6 6 4 7 3 9 7 nil
69
6 4 7 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4, 6, 7 6 4 7 3 9 7
70
6 4 7 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4, 6, 7 6 4 7 3 9 7
71
6 4 7 3 9 7 nil Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4, 6, 7 6 4 7 3 9 7 nil
72
6 4 7 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4, 6, 7 6 4 7 3 9 7
73
6 4 7 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4, 6, 7, 7 6 4 7 3 9 7
74
6 4 7 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4, 6, 7, 7 6 4 7 3 9 7
75
6 4 7 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4, 6, 7, 7 6 4 7 3 9 7
76
6 4 7 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4, 6, 7, 7 6 4 7 3 9 7
77
6 4 7 3 9 7 nil Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4, 6, 7, 7 6 4 7 3 9 7 nil
78
6 4 7 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4, 6, 7, 7, 9 6 4 7 3 9 7
79
6 4 7 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4, 6, 7, 7, 9 6 4 7 3 9 7
80
6 4 7 3 9 7 nil Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4, 6, 7, 7, 9 6 4 7 3 9 7 nil
81
6 4 7 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4, 6, 7, 7, 9 6 4 7 3 9 7
82
6 4 7 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4, 6, 7, 7, 9 6 4 7 3 9 7
83
6 4 7 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4, 6, 7, 7, 9 6 4 7 3 9 7
84
6 4 7 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4, 6, 7, 7, 9 6 4 7 3 9 7
85
6 4 7 3 9 7 Datenstrukturen Ausgabe: Inorder-Tree-Walk(x)
1. if xnil then 2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Ausgabe: 3, 4, 6, 7, 7, 9 6 4 7 3 9 7
86
Datenstrukturen Lemma 37
Inorder-Tree-Walk gibt die Schlüssel eines binären Suchbaums in aufsteigender Reihenfolge aus.
87
Datenstrukturen „Normale“ Induktion
Wir wollen zeigen, dass Aussage A(i) für alle natürlichen Zahlen i gilt Dazu beweisen wir, dass (a) A(1) gilt (b) Wenn A(i) gilt, dann gilt auch A(i+1) (a) heißt Induktionsanfang (b) nennt man Induktionsschluss (oder auch Induktionsschritt) Die Vorraussetzung in (b) (also A(i)) heißt Induktionsvoraussetzung
88
Aussage gilt für Bäume A und B
Datenstrukturen Induktion über die Struktur von Binärbäumen Wollen zeigen, dass Aussage für alle Binärbäume gilt: (a) Zeige Induktionsanfang für „kleine Binärbäume“ (b) Setze größere Bäume aus kleinen Binärbäumen zusammen, d.h. Aussage gilt für Bäume A und B A B
89
Dann gilt Aussage auch für neuen Baum mit Wurzel v
Datenstrukturen Induktion über die Struktur von Binärbäumen Wollen zeigen, dass Aussage für alle Binärbäume gilt: (a) Zeige Induktionsanfang für „kleine Binärbäume“ (b) Setze größere Bäume aus kleinen Binärbäumen zusammen, d.h. Dann gilt Aussage auch für neuen Baum mit Wurzel v v A B
90
Datenstrukturen Definition Beispiel
Die Höhe eines Binärbaums mit Wurzel v ist die Länge (Anzahl Kanten) des längsten einfachen Weges (keine mehrfach vorkommenden Knoten) von der Wurzel zu einem Blatt. Beispiel Baum der Höhe 3 v
91
Datenstrukturen Definition Beispiel
Die Höhe eines Binärbaums mit Wurzel v ist die Länge (Anzahl Kanten) des längsten einfachen Weges (keine mehrfach vorkommenden Knoten) von der Wurzel zu einem Blatt. Beispiel Baum der Höhe 1 v
92
Datenstrukturen Definition Beispiel
Die Höhe eines Binärbaums mit Wurzel v ist die Länge (Anzahl Kanten) des längsten einfachen Weges (keine mehrfach vorkommenden Knoten) von der Wurzel zu einem Blatt. Beispiel Baum der Höhe 0 v
93
Datenstrukturen Definition Beispiel
Die Höhe eines Binärbaums mit Wurzel v ist die Länge (Anzahl Kanten) des längsten einfachen Weges (keine mehrfach vorkommenden Knoten) von der Wurzel zu einem Blatt. Beispiel Übereinkunft: Ein leerer Baum hat Höhe -1 Damit gilt: Höhe eines Baumes mit Wurzel v und Teilbäumen A und B ist 1 + max{ Höhe(A), Höhe(B)} v A B
94
Datenstrukturen Induktion über die Struktur von Binärbäumen
Wir wollen Aussage A(i) durch Induktion über die Höhe von Bäumen zeigen (a) Zeige die Aussage für leere Bäume (Bäume der Höhe -1) (b) Zeige: Gilt die Aussage für Bäume der Höhe i, so gilt sie auch für Bäume der Höhe i+1 v A B
95
Datenstrukturen Induktion über die Struktur von Binärbäumen
Wir wollen Aussage A(i) durch Induktion über die Höhe von Bäumen zeigen (a) Zeige die Aussage für leere Bäume (Bäume der Höhe -1) (b) Zeige: Gilt die Aussage für Bäume der Höhe i, so gilt sie auch für Bäume der Höhe i+1 Dabei können wir immer annehmen, dass ein Baum der Höhe i+1 aus einer Wurzel v und zwei Teilbäumen A,B besteht, so dass (1) A und B Höhe maximal i haben und (2) A oder B Höhe i hat v A B Höhe i+1
96
Datenstrukturen Induktion über die Struktur von Binärbäumen
Wir wollen Aussage A(i) durch Induktion über die Höhe von Bäumen zeigen (a) Zeige die Aussage für leere Bäume (Bäume der Höhe -1) (b) Zeige: Gilt die Aussage für Bäume der Höhe i, so gilt sie auch für Bäume der Höhe i+1 Dabei können wir immer annehmen, dass ein Baum der Höhe i+1 aus einer Wurzel v und zwei Teilbäumen A,B besteht, so dass (1) A und B Höhe maximal i haben und (2) A oder B Höhe i hat v A B Höhe i
97
Datenstrukturen Lemma 37 Beweis Inorder-Tree-Walk(x) 1. if xnil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Lemma 37 Inorder-Tree-Walk gibt die Schlüssel eines binären Suchbaums in aufsteigender Reihenfolge aus. Beweis (I.A.) Ist die Eingabe ein leerer Baum, so wird Inorder-Tree-Walk nil übergeben. Damit bricht der Algorithmus sofort ab. Es gibt also keine Ausgabe, was auch korrekt ist. (I.V.) Das Lemma gilt für Bäume der Höhe ≤i. (I.S.) Wir müssen zeigen, dass das Lemma auch für Höhe i+1≥0. Dazu betrachten wir den Inorder-Tree-Walk auf einem solchem Baum. v A B
98
Datenstrukturen Lemma 37 Beweis Inorder-Tree-Walk(x) 1. if xnil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Lemma 37 Inorder-Tree-Walk gibt die Schlüssel eines binären Suchbaums in aufsteigender Reihenfolge aus. Beweis (I.S.) Wir müssen zeigen, dass das Lemma auch für Höhe i+1≥0. Dazu betrachten wir den Inorder-Tree-Walk auf einem solchem Baum. Da der Baum Höhe mindestens 0 hat, wird der Algorithmus nicht mit nil aufgerufen. Damit wird Zeile 2 ausgeführt. Dort wird Inorder-Tree-Walk rekursiv mit dem Teilbaum A der Höhe ≤i ausgeführt. Nach (I.V.) werden die Schlüssel aus A in aufsteigender Reihenfolge ausgegeben v A B
99
Datenstrukturen Lemma 37 Beweis Inorder-Tree-Walk(x) 1. if xnil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Lemma 37 Inorder-Tree-Walk gibt die Schlüssel eines binären Suchbaums in aufsteigender Reihenfolge aus. Beweis Nach (I.V.) werden die Schlüssel aus A in aufsteigender Reihenfolge ausgegeben. Dann wird in Zeile 3 key[v] ausgegeben. Wegen der Suchbaumeigenschaft ist key[v] größer gleich allen Schlüsseln in A und kleiner als alle Schlüssel in B. In Zeile 4 wird dann Inorder-Tree-Walk rekursiv für Teilbaum B aufgerufen. Die dort gespeicherten Schlüssel werden nach (I.V.) ebenfalls in aufsteigender Reihenfolge ausgegeben. v A B
100
Datenstrukturen Lemma 37 Beweis Inorder-Tree-Walk(x) 1. if xnil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x] 4. Inorder-Tree-Walk(rc[x]) Lemma 37 Inorder-Tree-Walk gibt die Schlüssel eines binären Suchbaums in aufsteigender Reihenfolge aus. Beweis Zusammenfassend werden also erst die Schlüssel in Teilbaum A in aufsteigender Reihenfolge ausgegeben. Dann folgt key[v] und dann die Schlüssel aus B in aufsteigender Reihenfolge. Aufgrund der Suchbaum- eigenschaft ist die gesamte Folge aufsteigend sortiert. v A B
101
6 4 7 3 9 7 Datenstrukturen Suchen in Binärbäumen
Gegeben ist Schlüssel k Gesucht ist ein Knoten mit Schlüssel k 6 4 7 3 9 7
102
6 4 7 3 9 7 Datenstrukturen Baumsuche(x,k)
1. if x=nil or k=key[x] then return x 2. if k<key[x] then return Baumsuche(lc[x],k) 3. else return Baumsuche(rc[x],k) 6 4 7 3 9 7
103
6 4 7 3 9 7 Datenstrukturen Baumsuche(root[T],9) Aufruf mit x=root[T]
Baumsuche(x,k) 1. if x=nil or k=key[x] then return x 2. if k<key[x] then return Baumsuche(lc[x],k) 3. else return Baumsuche(rc[x],k) Baumsuche(root[T],9) 6 4 7 3 9 7
104
6 4 7 3 9 7 Datenstrukturen Baumsuche(root[T],9) Baumsuche(x,k)
1. if x=nil or k=key[x] then return x 2. if k<key[x] then return Baumsuche(lc[x],k) 3. else return Baumsuche(rc[x],k) Baumsuche(root[T],9) 6 4 7 3 9 7
105
6 4 7 3 9 7 Datenstrukturen Baumsuche(root[T],9) Baumsuche(x,k)
1. if x=nil or k=key[x] then return x 2. if k<key[x] then return Baumsuche(lc[x],k) 3. else return Baumsuche(rc[x],k) Baumsuche(root[T],9) 6 4 7 3 9 7
106
6 4 7 3 9 7 Datenstrukturen Baumsuche(root[T],9) Baumsuche(x,k)
1. if x=nil or k=key[x] then return x 2. if k<key[x] then return Baumsuche(lc[x],k) 3. else return Baumsuche(rc[x],k) Baumsuche(root[T],9) 6 4 7 3 9 7
107
6 4 7 3 9 7 Datenstrukturen Baumsuche(root[T],9) Baumsuche(x,k)
1. if x=nil or k=key[x] then return x 2. if k<key[x] then return Baumsuche(lc[x],k) 3. else return Baumsuche(rc[x],k) Baumsuche(root[T],9) 6 4 7 3 9 7
108
6 4 7 3 9 7 Datenstrukturen Baumsuche(root[T],9) Baumsuche(x,k)
1. if x=nil or k=key[x] then return x 2. if k<key[x] then return Baumsuche(lc[x],k) 3. else return Baumsuche(rc[x],k) Baumsuche(root[T],9) 6 4 7 3 9 7
109
6 4 7 3 9 7 Datenstrukturen Baumsuche(root[T],9) Baumsuche(x,k)
1. if x=nil or k=key[x] then return x 2. if k<key[x] then return Baumsuche(lc[x],k) 3. else return Baumsuche(rc[x],k) Baumsuche(root[T],9) 6 4 7 3 9 7
110
6 4 7 3 9 7 Datenstrukturen Ausgabe: 9 Baumsuche(root[T],9)
Baumsuche(x,k) 1. if x=nil or k=key[x] then return x 2. if k<key[x] then return Baumsuche(lc[x],k) 3. else return Baumsuche(rc[x],k) Ausgabe: 9 Baumsuche(root[T],9) 6 4 7 3 9 7
111
Laufzeit: O(h) 6 4 7 3 9 7 Datenstrukturen Höhe h Baumsuche(x,k)
1. if x=nil or k=key[x] then return x 2. if k<key[x] then return Baumsuche(lc[x],k) 3. else return Baumsuche(rc[x],k) Laufzeit: O(h) 6 4 7 Höhe h 3 9 7
112
6 4 7 3 9 7 Datenstrukturen IterativeBaumsuche(x,k)
1. while xnil and kkey[x] do if k<key[x] then x lc[x] else x rc[x] 4. return x 6 4 7 3 9 7
113
6 4 7 3 9 7 Datenstrukturen IterativeBaumsuche(x,k)
1. while xnil and kkey[x] do if k<key[x] then x lc[x] else x rc[x] 4. return x Aufruf mit x=root[T] 6 4 7 3 9 7
114
6 4 7 3 9 7 Datenstrukturen Baumsuche(root[T],5)
IterativeBaumsuche(x,k) 1. while xnil and kkey[x] do if k<key[x] then x lc[x] else x rc[x] 4. return x Aufruf mit x=root[T] Baumsuche(root[T],5) 6 4 7 3 9 7
115
x 6 4 7 3 9 7 Datenstrukturen Baumsuche(root[T],5)
IterativeBaumsuche(x,k) 1. while xnil and kkey[x] do if k<key[x] then x lc[x] else x rc[x] 4. return x x Baumsuche(root[T],5) 6 4 7 3 9 7
116
6 x 4 7 3 9 7 Datenstrukturen Baumsuche(root[T],5)
IterativeBaumsuche(x,k) 1. while xnil and kkey[x] do if k<key[x] then x lc[x] else x rc[x] 4. return x Baumsuche(root[T],5) 6 x 4 7 3 9 7
117
6 x 4 7 3 9 7 Datenstrukturen Baumsuche(root[T],5)
IterativeBaumsuche(x,k) 1. while xnil and kkey[x] do if k<key[x] then x lc[x] else x rc[x] 4. return x Baumsuche(root[T],5) 6 x 4 7 3 9 7
118
6 x 4 7 3 9 7 Datenstrukturen Baumsuche(root[T],5)
IterativeBaumsuche(x,k) 1. while xnil and kkey[x] do if k<key[x] then x lc[x] else x rc[x] 4. return x Aufruf mit x=root[T] Baumsuche(root[T],5) 6 x 4 7 3 9 7
119
6 4 7 x nil 3 9 7 Datenstrukturen Baumsuche(root[T],5)
IterativeBaumsuche(x,k) 1. while xnil and kkey[x] do if k<key[x] then x lc[x] else x rc[x] 4. return x Baumsuche(root[T],5) 6 4 7 x nil 3 9 7
120
6 4 7 x nil 3 9 7 Datenstrukturen Baumsuche(root[T],5)
IterativeBaumsuche(x,k) 1. while xnil and kkey[x] do if k<key[x] then x lc[x] else x rc[x] 4. return x Baumsuche(root[T],5) 6 4 7 x nil 3 9 7
121
6 4 7 x nil 3 9 7 Datenstrukturen Baumsuche(root[T],5)
IterativeBaumsuche(x,k) 1. while xnil and kkey[x] do if k<key[x] then x lc[x] else x rc[x] 4. return x Baumsuche(root[T],5) 6 4 7 x nil 3 9 7
122
6 4 7 3 9 7 Datenstrukturen Funktionsweise wie (rekursive)
Baumsuche. Laufzeit ebenfalls O(h). IterativeBaumsuche(x,k) 1. while xnil and kkey[x] do if k<key[x] then x lc[x] else x rc[x] 4. return x 6 4 7 3 9 7
123
6 4 7 3 9 7 Datenstrukturen Minimum- und Maximumsuche
Suchbaumeigenschaft: Alle Knoten im rechten Unterbaum eines Knotens x sind größer key[x] Alle Knoten im linken Unterbaum von x sind key[x] 6 4 7 3 9 7
124
Wird mit Wurzel aufgerufen
Datenstrukturen Wird mit Wurzel aufgerufen MinimumSuche(x) 1. while lc[x]nil do x lc[x] 2. return x 6 4 7 3 9 7
125
Wird mit Wurzel aufgerufen
Datenstrukturen Wird mit Wurzel aufgerufen Laufzeit O(h) MinimumSuche(x) 1. while lc[x]nil do x lc[x] 2. return x 6 4 7 3 9 7
126
Wird mit Wurzel aufgerufen
Datenstrukturen Wird mit Wurzel aufgerufen Laufzeit O(h) MaximumSuche(x) 1. while rc[x]nil do x rc[x] 2. return x 6 4 7 3 9 7
127
6 4 7 3 9 7 Datenstrukturen Nachfolgersuche
Nachfolger bzgl. Inorder-Tree-Walk Wenn alle Schlüssel unterschiedlich, dann ist das der nächstgrößere Schlüssel 6 4 7 3 9 7
128
6 4 7 3 9 7 Datenstrukturen Nachfolgersuche
Fall 1 (rechter Unterbaum von x nicht leer): Dann ist der linkeste Knoten im rechten Unterbaum der Nachfolger von x 6 4 7 3 9 7
129
6 4 7 3 9 7 Datenstrukturen Nachfolgersuche
Fall 1 (rechter Unterbaum von x nicht leer): Dann ist der linkeste Knoten im rechten Unterbaum der Nachfolger von x 6 4 7 3 9 7
130
6 4 7 3 9 7 Datenstrukturen Nachfolgersuche
Fall 1 (rechter Unterbaum von x nicht leer): Dann ist der linkeste Knoten im rechten Unterbaum der Nachfolger von x 6 4 7 3 9 7
131
6 4 7 3 5 9 Datenstrukturen Nachfolgersuche
Fall 2 (rechter Unterbaum von x leer und x hat Nachfolger y): Dann ist y der erste Knoten auf dem Pfad zur Wurzel, der größer als x ist 6 4 7 3 5 9
132
6 4 7 3 5 9 Datenstrukturen Nachfolgersuche
Fall 2 (rechter Unterbaum von x leer und x hat Nachfolger y): Dann ist y der erste Knoten auf dem Pfad zur Wurzel, der größer als x ist 6 4 7 3 5 9
133
6 4 7 3 5 9 Datenstrukturen Nachfolgersuche
Fall 2 (rechter Unterbaum von x leer und x hat Nachfolger y): Dann ist y der erste Knoten auf dem Pfad zur Wurzel, der größer als x ist 6 4 7 3 5 9
134
6 4 7 3 5 9 Datenstrukturen Nachfolgersuche(x)
1. if rc[x] nil then return MinimumSuche(rc[x]) 2. y p[x] 3. while y nil and x=rc[y] do x y y p[y] 6. return y 6 4 7 3 5 9
135
6 4 7 3 5 9 Datenstrukturen Nachfolgersuche(6) Nachfolgersuche(x)
1. if rc[x] nil then return MinimumSuche(rc[x]) 2. y p[x] 3. while y nil and x=rc[y] do x y y p[y] 6. return y Nachfolgersuche(6) 6 4 7 3 5 9
136
6 4 7 3 5 9 Datenstrukturen Nachfolgersuche(6) Nachfolgersuche(x)
1. if rc[x] nil then return MinimumSuche(rc[x]) 2. y p[x] 3. while y nil and x=rc[y] do x y y p[y] 6. return y Nachfolgersuche(6) 6 4 7 3 5 9
137
6 4 7 3 5 9 Datenstrukturen Nachfolgersuche(6) Nachfolgersuche(x)
1. if rc[x] nil then return MinimumSuche(rc[x]) 2. y p[x] 3. while y nil and x=rc[y] do x y y p[y] 6. return y Nachfolgersuche(6) 6 4 7 3 5 9
138
6 4 7 3 5 9 Datenstrukturen Nachfolgersuche(5) Nachfolgersuche(x)
1. if rc[x] nil then return MinimumSuche(rc[x]) 2. y p[x] 3. while y nil and x=rc[y] do x y y p[y] 6. return y Nachfolgersuche(5) 6 4 7 3 5 9
139
6 4 7 3 5 9 Datenstrukturen Nachfolgersuche(5) Nachfolgersuche(x)
1. if rc[x] nil then return MinimumSuche(rc[x]) 2. y p[x] 3. while y nil and x=rc[y] do x y y p[y] 6. return y Nachfolgersuche(5) 6 4 7 3 5 9
140
6 y 4 7 3 5 9 Datenstrukturen Nachfolgersuche(5) Nachfolgersuche(x)
1. if rc[x] nil then return MinimumSuche(rc[x]) 2. y p[x] 3. while y nil and x=rc[y] do x y y p[y] 6. return y Nachfolgersuche(5) 6 y 4 7 3 5 9
141
6 y 4 7 3 5 9 Datenstrukturen Nachfolgersuche(5) Nachfolgersuche(x)
1. if rc[x] nil then return MinimumSuche(rc[x]) 2. y p[x] 3. while y nil and x=rc[y] do x y y p[y] 6. return y Nachfolgersuche(5) 6 y 4 7 3 5 9
142
6 y 4 7 3 5 x 9 Datenstrukturen Nachfolgersuche(5) Nachfolgersuche(x)
1. if rc[x] nil then return MinimumSuche(rc[x]) 2. y p[x] 3. while y nil and x=rc[y] do x y y p[y] 6. return y Nachfolgersuche(5) 6 y 4 7 3 5 x 9
143
6 y 4 x 7 3 5 9 Datenstrukturen Nachfolgersuche(5) Nachfolgersuche(x)
1. if rc[x] nil then return MinimumSuche(rc[x]) 2. y p[x] 3. while y nil and x=rc[y] do x y y p[y] 6. return y Nachfolgersuche(5) 6 y 4 x 7 3 5 9
144
y 6 4 x 7 3 5 9 Datenstrukturen Nachfolgersuche(5) Nachfolgersuche(x)
1. if rc[x] nil then return MinimumSuche(rc[x]) 2. y p[x] 3. while y nil and x=rc[y] do x y y p[y] 6. return y Nachfolgersuche(5) y 6 4 x 7 3 5 9
145
y 6 4 x 7 3 5 9 Datenstrukturen Nachfolgersuche(5) Nachfolgersuche(x)
1. if rc[x] nil then return MinimumSuche(rc[x]) 2. y p[x] 3. while y nil and x=rc[y] do x y y p[y] 6. return y Nachfolgersuche(5) y 6 4 x 7 3 5 9
146
y 6 4 x 7 3 5 9 Datenstrukturen Nachfolgersuche(5) Nachfolgersuche(x)
1. if rc[x] nil then return MinimumSuche(rc[x]) 2. y p[x] 3. while y nil and x=rc[y] do x y y p[y] 6. return y Nachfolgersuche(5) y 6 4 x 7 3 5 9
147
Laufzeit O(h) 6 4 7 3 5 9 Datenstrukturen Nachfolgersuche(x)
1. if rc[x] nil then return MinimumSuche(rc[x]) 2. y p[x] 3. while y nil and x=rc[y] do x y y p[y] 6. return y 6 4 7 3 5 9
148
Laufzeit O(h) 6 4 7 3 5 9 Datenstrukturen Vorgängersuche
Symmetrisch zu Nachfolgersuche Daher ebenfall O(h) Laufzeit 6 4 7 3 5 9
149
Datenstrukturen Binäre Suchbäume Dynamische Operationen?
Aufzählen der Elemente mit Inorder-Tree-Walk in O(n) Zeit Suche in O(h) Zeit Minimum/Maximum in O(h) Zeit Vorgänger/Nachfolger in O(h) Zeit Dynamische Operationen? Einfügen und Löschen Müssen Suchbaumeigenschaft aufrecht erhalten Auswirkung auf Höhe des Baums?
150
6 4 7 3 5 9 Datenstrukturen Einfügen
Ähnlich wie Baumsuche: Finde Blatt, an das neuer Knoten angehängt wird Danach wird nil-Zeiger durch neues Element ersetzt 6 4 7 3 5 9
151
6 4 7 3 5 9 Datenstrukturen Einfügen(T,z) 1. y nil; x root[T]
2. while xnil do y x if key[z] < key[x] then x lc[x] else x rc[x] 6. p[z] y 7. if y=nil then root[T] z 8. else if key[z]< key[y] then lc[y] z else rc[y] z 6 4 7 3 5 9
152
x 6 4 7 3 5 9 Datenstrukturen Einfügen(8)
y wird Vater des einzufügenden Elements Einfügen(T,z) 1. y nil; x root[T] 2. while xnil do y x if key[z] < key[x] then x lc[x] else x rc[x] 6. p[z] y 7. if y=nil then root[T] z 8. else if key[z]< key[y] then lc[y] z else rc[y] z Einfügen(8) x 6 4 7 3 5 9
153
x 6 4 7 3 5 9 Datenstrukturen Einfügen(8) Einfügen(T,z)
1. y nil; x root[T] 2. while xnil do y x if key[z] < key[x] then x lc[x] else x rc[x] 6. p[z] y 7. if y=nil then root[T] z 8. else if key[z]< key[y] then lc[y] z else rc[y] z Einfügen(8) x 6 4 7 3 5 9
154
x 6 y 4 7 3 5 9 Datenstrukturen Einfügen(8) Einfügen(T,z)
1. y nil; x root[T] 2. while xnil do y x if key[z] < key[x] then x lc[x] else x rc[x] 6. p[z] y 7. if y=nil then root[T] z 8. else if key[z]< key[y] then lc[y] z else rc[y] z Einfügen(8) x 6 y 4 7 3 5 9
155
x 6 y 4 7 3 5 9 Datenstrukturen Einfügen(8) Einfügen(T,z)
1. y nil; x root[T] 2. while xnil do y x if key[z] < key[x] then x lc[x] else x rc[x] 6. p[z] y 7. if y=nil then root[T] z 8. else if key[z]< key[y] then lc[y] z else rc[y] z Einfügen(8) x 6 y 4 7 3 5 9
156
y 6 x 4 7 3 5 9 Datenstrukturen Einfügen(8) Einfügen(T,z)
1. y nil; x root[T] 2. while xnil do y x if key[z] < key[x] then x lc[x] else x rc[x] 6. p[z] y 7. if y=nil then root[T] z 8. else if key[z]< key[y] then lc[y] z else rc[y] z Einfügen(8) 6 y x 4 7 3 5 9
157
y 6 x 4 7 3 5 9 Datenstrukturen Einfügen(8) Einfügen(T,z)
1. y nil; x root[T] 2. while xnil do y x if key[z] < key[x] then x lc[x] else x rc[x] 6. p[z] y 7. if y=nil then root[T] z 8. else if key[z]< key[y] then lc[y] z else rc[y] z Einfügen(8) 6 y x 4 7 3 5 9
158
6 x 4 7 y 3 5 9 Datenstrukturen Einfügen(8) Einfügen(T,z)
1. y nil; x root[T] 2. while xnil do y x if key[z] < key[x] then x lc[x] else x rc[x] 6. p[z] y 7. if y=nil then root[T] z 8. else if key[z]< key[y] then lc[y] z else rc[y] z Einfügen(8) 6 x 4 7 y 3 5 9
159
6 x 4 7 y 3 5 9 Datenstrukturen Einfügen(8) Einfügen(T,z)
1. y nil; x root[T] 2. while xnil do y x if key[z] < key[x] then x lc[x] else x rc[x] 6. p[z] y 7. if y=nil then root[T] z 8. else if key[z]< key[y] then lc[y] z else rc[y] z Einfügen(8) 6 x 4 7 y 3 5 9
160
6 4 7 y x 3 5 9 Datenstrukturen Einfügen(8) Einfügen(T,z)
1. y nil; x root[T] 2. while xnil do y x if key[z] < key[x] then x lc[x] else x rc[x] 6. p[z] y 7. if y=nil then root[T] z 8. else if key[z]< key[y] then lc[y] z else rc[y] z Einfügen(8) 6 4 7 y x 3 5 9
161
6 4 7 y x 3 5 9 Datenstrukturen Einfügen(8) Einfügen(T,z)
1. y nil; x root[T] 2. while xnil do y x if key[z] < key[x] then x lc[x] else x rc[x] 6. p[z] y 7. if y=nil then root[T] z 8. else if key[z]< key[y] then lc[y] z else rc[y] z Einfügen(8) 6 4 7 y x 3 5 9
162
6 4 7 x 3 y 5 9 Datenstrukturen Einfügen(8) Einfügen(T,z)
1. y nil; x root[T] 2. while xnil do y x if key[z] < key[x] then x lc[x] else x rc[x] 6. p[z] y 7. if y=nil then root[T] z 8. else if key[z]< key[y] then lc[y] z else rc[y] z Einfügen(8) 6 4 7 x 3 5 y 9
163
6 4 7 3 y 5 9 x nil Datenstrukturen Einfügen(8) Einfügen(T,z)
1. y nil; x root[T] 2. while xnil do y x if key[z] < key[x] then x lc[x] else x rc[x] 6. p[z] y 7. if y=nil then root[T] z 8. else if key[z]< key[y] then lc[y] z else rc[y] z Einfügen(8) 6 4 7 3 5 y 9 x nil
164
6 4 7 3 y 5 9 x nil Datenstrukturen Einfügen(8) Einfügen(T,z)
1. y nil; x root[T] 2. while xnil do y x if key[z] < key[x] then x lc[x] else x rc[x] 6. p[z] y 7. if y=nil then root[T] z 8. else if key[z]< key[y] then lc[y] z else rc[y] z Einfügen(8) 6 4 7 3 5 y 9 x nil
165
6 4 7 3 y 5 9 x nil Datenstrukturen Einfügen(8) Einfügen(T,z)
1. y nil; x root[T] 2. while xnil do y x if key[z] < key[x] then x lc[x] else x rc[x] 6. p[z] y 7. if y=nil then root[T] z 8. else if key[z]< key[y] then lc[y] z else rc[y] z Einfügen(8) 6 4 7 3 5 y 9 x nil
166
6 4 7 3 y 5 9 x 8 Datenstrukturen Einfügen(8) Einfügen(T,z)
1. y nil; x root[T] 2. while xnil do y x if key[z] < key[x] then x lc[x] else x rc[x] 6. p[z] y 7. if y=nil then root[T] z 8. else if key[z]< key[y] then lc[y] z else rc[y] z Einfügen(8) 6 4 7 3 5 y 9 x 8
167
6 4 7 3 y 5 9 x 8 Datenstrukturen Einfügen(8) Einfügen(T,z)
1. y nil; x root[T] 2. while xnil do y x if key[z] < key[x] then x lc[x] else x rc[x] 6. p[z] y 7. if y=nil then root[T] z 8. else if key[z]< key[y] then lc[y] z else rc[y] z Einfügen(8) 6 4 7 3 5 y 9 x 8
168
Laufzeit O(h) 6 4 7 3 5 9 8 Datenstrukturen Einfügen(T,z)
1. y nil; x root[T] 2. while xnil do y x if key[z] < key[x] then x lc[x] else x rc[x] 6. p[z] y 7. if y=nil then root[T] z 8. else if key[z]< key[y] then lc[y] z else rc[y] z 6 4 7 3 5 9 8
169
6 4 7 3 5 9 Datenstrukturen Löschen 3 unterschiedliche Fälle
(a) zu löschendes Element z hat keine Kinder (b) zu löschendes Element z hat ein Kind (c) zu löschendes Element z hat zwei Kinder 6 4 7 3 5 9
170
6 4 7 3 5 9 Datenstrukturen Fall (a)
zu löschendes Element z hat keine Kinder 6 4 7 3 5 9
171
6 6 4 7 4 7 3 5 9 3 9 Datenstrukturen Fall (a)
zu löschendes Element z hat keine Kinder Entferne Element 6 6 4 7 4 7 3 5 9 3 9
172
6 4 7 3 5 9 Datenstrukturen Fall (b)
Zu löschendes Element z hat 1 Kind 6 4 7 3 5 9
173
6 6 4 7 4 9 3 5 9 3 5 Datenstrukturen Fall (b)
Zu löschendes Element z hat 1 Kind 6 6 4 7 4 9 3 5 9 3 5
174
6 4 7 3 5 9 Datenstrukturen Fall (c)
Zu löschendes Element z hat 2 Kinder 6 4 7 3 5 9
175
6 4 7 3 5 9 Datenstrukturen Fall (c)
Zu löschendes Element z hat 2 Kinder Schritt 1: Bestimme Nachfolger von z 6 4 7 3 5 9
176
Nachfolger hat nur ein Kind
Datenstrukturen Fall (c) Zu löschendes Element z hat 2 Kinder Schritt 1: Bestimme Nachfolger von z Nachfolger hat nur ein Kind 6 6 4 7 4 9 3 5 9 3 5
177
6 6 4 7 4 9 3 5 9 3 5 Datenstrukturen Fall (c)
Zu löschendes Element z hat 2 Kinder Schritt 1: Bestimme Nachfolger von z Schritt 2: Entferne Nachfolger 6 6 4 7 4 9 3 5 9 3 5
178
6 7 4 7 4 9 3 5 9 3 5 Datenstrukturen Fall (c)
Zu löschendes Element z hat 2 Kinder Schritt 1: Bestimme Nachfolger von z Schritt 2: Entferne Nachfolger Schritt 3: Ersetze z durch Nachfolger 6 7 4 7 4 9 3 5 9 3 5
179
6 4 7 3 5 9 Datenstrukturen Löschen(T,z)
1. if lc[z]=nil or rc[z]=nil then y z 2. else y NachfolgerSuche(z) 3. if lc[y] nil then x lc[y] 4. else x rc[y] 5. if x nil then p[x] p[y] 6. if p[y]=nil then root[T] x 7. else if y=lc[p[y]] then lc[p[y]] x else rc[p[y]] x 9. key[z] key[y] 6 4 7 3 5 9
180
Löschen(6) 6 4 7 3 5 9 Datenstrukturen Referenz auf z wird übergeben!
Löschen(T,z) 1. if lc[z]=nil or rc[z]=nil then y z 2. else y NachfolgerSuche(z) 3. if lc[y] nil then x lc[y] 4. else x rc[y] 5. if x nil then p[x] p[y] 6. if p[y]=nil then root[T] x 7. else if y=lc[p[y]] then lc[p[y]] x else rc[p[y]] x 9. key[z] key[y] Löschen(6) 6 4 7 3 5 9
181
Löschen(6) z 6 4 7 3 5 9 Datenstrukturen
Bestimme Knoten, der gelöscht werden soll. Der Knoten hat nur einen Nachfolger Löschen(T,z) 1. if lc[z]=nil or rc[z]=nil then y z 2. else y NachfolgerSuche(z) 3. if lc[y] nil then x lc[y] 4. else x rc[y] 5. if x nil then p[x] p[y] 6. if p[y]=nil then root[T] x 7. else if y=lc[p[y]] then lc[p[y]] x else rc[p[y]] x 9. key[z] key[y] Löschen(6) z 6 4 7 3 5 9
182
Löschen(6) z 6 4 7 y 3 5 9 Datenstrukturen
Bestimme Knoten, der gelöscht werden soll. Der Knoten hat nur einen Nachfolger Löschen(T,z) 1. if lc[z]=nil or rc[z]=nil then y z 2. else y NachfolgerSuche(z) 3. if lc[y] nil then x lc[y] 4. else x rc[y] 5. if x nil then p[x] p[y] 6. if p[y]=nil then root[T] x 7. else if y=lc[p[y]] then lc[p[y]] x else rc[p[y]] x 9. key[z] key[y] Löschen(6) z 6 4 7 y 3 5 9
183
Löschen(6) z 6 4 7 y 3 5 9 x Datenstrukturen Löschen(T,z)
Bestimme das Kind von y, falls existent Löschen(T,z) 1. if lc[z]=nil or rc[z]=nil then y z 2. else y NachfolgerSuche(z) 3. if lc[y] nil then x lc[y] 4. else x rc[y] 5. if x nil then p[x] p[y] 6. if p[y]=nil then root[T] x 7. else if y=lc[p[y]] then lc[p[y]] x else rc[p[y]] x 9. key[z] key[y] Löschen(6) z 6 4 7 y 3 5 9 x
184
Löschen(6) z 6 4 7 y 3 5 9 x Datenstrukturen Löschen(T,z)
1. if lc[z]=nil or rc[z]=nil then y z 2. else y NachfolgerSuche(z) 3. if lc[y] nil then x lc[y] 4. else x rc[y] 5. if x nil then p[x] p[y] 6. if p[y]=nil then root[T] x 7. else if y=lc[p[y]] then lc[p[y]] x else rc[p[y]] x 9. key[z] key[y] Aktualisiere Vaterzeiger von x Löschen(6) z 6 4 7 y 3 5 9 x
185
Löschen(6) z 6 4 7 y 3 5 9 x Datenstrukturen Löschen(T,z)
1. if lc[z]=nil or rc[z]=nil then y z 2. else y NachfolgerSuche(z) 3. if lc[y] nil then x lc[y] 4. else x rc[y] 5. if x nil then p[x] p[y] 6. if p[y]=nil then root[T] x 7. else if y=lc[p[y]] then lc[p[y]] x else rc[p[y]] x 9. key[z] key[y] Löschen(6) z 6 4 7 y 3 5 9 x
186
Löschen(6) z 6 4 7 y 3 5 9 x Datenstrukturen Löschen(T,z)
1. if lc[z]=nil or rc[z]=nil then y z 2. else y NachfolgerSuche(z) 3. if lc[y] nil then x lc[y] 4. else x rc[y] 5. if x nil then p[x] p[y] 6. if p[y]=nil then root[T] x 7. else if y=lc[p[y]] then lc[p[y]] x else rc[p[y]] x 9. key[z] key[y] Löschen(6) Das rechte Kind von z wird x. z 6 4 7 y 3 5 9 x
187
Löschen(6) z 6 7 y 4 3 5 9 x Datenstrukturen Löschen(T,z)
1. if lc[z]=nil or rc[z]=nil then y z 2. else y NachfolgerSuche(z) 3. if lc[y] nil then x lc[y] 4. else x rc[y] 5. if x nil then p[x] p[y] 6. if p[y]=nil then root[T] x 7. else if y=lc[p[y]] then lc[p[y]] x else rc[p[y]] x 9. key[z] key[y] Löschen(6) Das rechte Kind von z wird x. z 6 7 y 4 3 5 9 x
188
Löschen(6) z 7 4 3 5 9 x Datenstrukturen Löschen(T,z)
1. if lc[z]=nil or rc[z]=nil then y z 2. else y NachfolgerSuche(z) 3. if lc[y] nil then x lc[y] 4. else x rc[y] 5. if x nil then p[x] p[y] 6. if p[y]=nil then root[T] x 7. else if y=lc[p[y]] then lc[p[y]] x else rc[p[y]] x 9. key[z] key[y] Löschen(6) z 7 Umkopieren des Inhalts von y nach z 4 3 5 9 x
189
Löschen(6) z 7 4 9 3 5 Datenstrukturen Löschen(T,z)
1. if lc[z]=nil or rc[z]=nil then y z 2. else y NachfolgerSuche(z) 3. if lc[y] nil then x lc[y] 4. else x rc[y] 5. if x nil then p[x] p[y] 6. if p[y]=nil then root[T] x 7. else if y=lc[p[y]] then lc[p[y]] x else rc[p[y]] x 9. key[z] key[y] Löschen(6) z 7 4 9 3 5
190
Löschen(6) z 7 4 9 3 5 Datenstrukturen Laufzeit O(h) Löschen(T,z)
1. if lc[z]=nil or rc[z]=nil then y z 2. else y NachfolgerSuche(z) 3. if lc[y] nil then x lc[y] 4. else x rc[y] 5. if x nil then p[x] p[y] 6. if p[y]=nil then root[T] x 7. else if y=lc[p[y]] then lc[p[y]] x else rc[p[y]] x 9. key[z] key[y] Löschen(6) z 7 4 9 3 5
191
Datenstrukturen Binäre Suchbäume Frage Ausgabe aller Elemente in O(n)
Suche, Minimum, Maximum, Nachfolger in O(h) Einfügen, Löschen in O(h) Frage Wie kann man eine „kleine“ Höhe unter Einfügen und Löschen garantieren?
Ähnliche Präsentationen
© 2024 SlidePlayer.org Inc.
All rights reserved.