1
Datenstrukturen und Algorithmen
Christian Sohler
FG Algorithmen & Komplexität
2
Ein Datenbank-Problem
Problem:
• Gegeben sind n Objekte O ,.., O mit zugehörigen Schlüsseln s(O )
Operationen:
• Suche(x); Ausgabe O mit Schlüssel s(O) =x;
nil, falls kein Objekt mit Schlüssel x in Datenbank
• Einfügen(O); Einfügen von Objekt O in Datenbank
• Löschen(O); Löschen von Objekt O mit aus der Datenbank
1 n
i
3
Ein Datenbank-Problem
Drei grundlegende Datenstrukturen
• 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
4
Ein Datenbank-Problem
Binärbäume
• 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]
/
/ / / / / / / /
5
Ein Datenbank-Problem
Binäre Suchbäume
• 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
3
7
7 9
6
Ein Datenbank-Problem
Unterschiedliche Suchbäume
• Schlüsselmenge 3,4,6,7,7,9
• Wir erlauben mehrfache Vorkommen desselben Schlüssels
3
6
7
7 4
9 6
4 3
7
7 9
7
Ein Datenbank-Problem
Ausgabe aller Schlüssel
• Gegeben binärer Suchbaum
• Wie kann man alle Schlüssel aufsteigend sortiert in Θ(n) Zeit ausgeben?
6 4
3
7
7 9
8
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
9
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Aufruf über
Inorder-Tree-Walk(root[T])
10
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
11
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
12
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
13
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
14
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
15
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Kein linkes Kind vorhanden, d.h.
lc[x]=nil
x nil
16
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Kein linkes Kind vorhanden, d.h.
lc[x]=nil
x nil
17
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Ausgabe:
3
18
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Ausgabe:
3
Kein rechtes Kind vorhanden, d.h.
rc[x]=nil
nil
19
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Ausgabe:
3
Kein rechtes Kind vorhanden, d.h.
rc[x]=nil
nil
20
Ein Datenbank-Problem
Ausgabe:
3 Inorder-Tree-Walk(x)
1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Knoten abgearbeitet
21
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Ausgabe:
3, 4
22
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Ausgabe:
3, 4
nil
23
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Ausgabe:
3, 4
nil
24
Ein Datenbank-Problem
Ausgabe:
3, 4 Inorder-Tree-Walk(x)
1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
25
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Ausgabe:
3, 4, 6
26
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Ausgabe:
3, 4, 6
27
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Ausgabe:
3, 4, 6
28
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Ausgabe:
3, 4, 6
29
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Ausgabe:
3, 4, 6
30
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Ausgabe:
3, 4, 6
31
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Ausgabe:
3, 4, 6
nil
32
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Ausgabe:
3, 4, 6, 7
33
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Ausgabe:
3, 4, 6, 7
34
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Ausgabe:
3, 4, 6
nil
35
Ein Datenbank-Problem
Ausgabe:
3, 4, 6, 7 Inorder-Tree-Walk(x)
1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
36
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Ausgabe:
3, 4, 6, 7, 7
37
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Ausgabe:
3, 4, 6, 7, 7
38
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Ausgabe:
3, 4, 6, 7, 7
39
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Ausgabe:
3, 4, 6, 7, 7
40
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Ausgabe:
3, 4, 6, 7, 7
nil
41
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Ausgabe:
3, 4, 6, 7, 7
42
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Ausgabe:
3, 4, 6, 7, 7, 9
43
Ein Datenbank-Problem
Inorder-Tree-Walk(x) 1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
Ausgabe:
3, 4, 6, 7, 7, 9
nil
44
Ein Datenbank-Problem
Ausgabe:
3, 4, 6, 7, 7, 9 Inorder-Tree-Walk(x)
1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
45
Ein Datenbank-Problem
Ausgabe:
3, 4, 6, 7, 7, 9 Inorder-Tree-Walk(x)
1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
46
Ein Datenbank-Problem
Ausgabe:
3, 4, 6, 7, 7, 9 Inorder-Tree-Walk(x)
1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
47
Ein Datenbank-Problem
Ausgabe:
3, 4, 6, 7, 7, 9 Inorder-Tree-Walk(x)
1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
48
Ein Datenbank-Problem
Laufzeit Θ(n) Inorder-Tree-Walk(x)
1. if x≠nil then
2. Inorder-Tree-Walk(lc[x]) 3. Ausgabe key[x]
4. Inorder-Tree-Walk(rc[x]) 6 4
3
7
7 9
49
Ein Datenbank-Problem
Suchen in Binärbäumen
• Gegeben ist Schlüssel k
• Gesucht ist ein Knoten mit Schlüssel k
6 4
3
7
7 9
50
Ein Datenbank-Problem
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
3
7
7 9
51
Ein Datenbank-Problem
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
3
7
7 9
Aufruf mit x=root[T]
Baumsuche(root[T],9)
52
Ein Datenbank-Problem
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
3
7
7 9
Baumsuche(root[T],9)
53
Ein Datenbank-Problem
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
3
7
7 9
Baumsuche(root[T],9)
54
Ein Datenbank-Problem
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
3
7
7 9
Baumsuche(root[T],9)
55
Ein Datenbank-Problem
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
3
7
7 9
Baumsuche(root[T],9)
56
Ein Datenbank-Problem
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
3
7
7 9
Baumsuche(root[T],9)
57
Ein Datenbank-Problem
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
3
7
7 9
Baumsuche(root[T],9)
58
Ein Datenbank-Problem
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
3
7
7 9
Baumsuche(root[T],9)
59
Ein Datenbank-Problem
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
3
7
7 9
Baumsuche(root[T],9) Ausgabe: 9
60
Ein Datenbank-Problem
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
3
7
7 9
Laufzeit: O(h) Höhe h
61
Ein Datenbank-Problem
IterativeBaumsuche(x,k)
1. while x≠nil and k≠key[x] do 2. if k<key[x] then x ← lc[x]
3. else x ← rc[x]
4. return x
6 4
3
7
7 9
62
Ein Datenbank-Problem
IterativeBaumsuche(x,k)
1. while x≠nil and k≠key[x] do 2. if k<key[x] then x ← lc[x]
3. else x ← rc[x]
4. return x
6 4
3
7
7 9
Aufruf mit x=root[T]
63
Ein Datenbank-Problem
IterativeBaumsuche(x,k)
1. while x≠nil and k≠key[x] do 2. if k<key[x] then x ← lc[x]
3. else x ← rc[x]
4. return x
6 4
3
7
7 9
Aufruf mit x=root[T]
Baumsuche(root[T],5) x
64
Ein Datenbank-Problem
IterativeBaumsuche(x,k)
1. while x≠nil and k≠key[x] do 2. if k<key[x] then x ← lc[x]
3. else x ← rc[x]
4. return x
6 4
3
7
7 9
Baumsuche(root[T],5) x
65
Ein Datenbank-Problem
IterativeBaumsuche(x,k)
1. while x≠nil and k≠key[x] do 2. if k<key[x] then x ← lc[x]
3. else x ← rc[x]
4. return x
6 4
3
7
7 9
Baumsuche(root[T],5) x
66
Ein Datenbank-Problem
IterativeBaumsuche(x,k)
1. while x≠nil and k≠key[x] do 2. if k<key[x] then x ← lc[x]
3. else x ← rc[x]
4. return x
6 4
3
7
7 9
Baumsuche(root[T],5) x
67
Ein Datenbank-Problem
IterativeBaumsuche(x,k)
1. while x≠nil and k≠key[x] do 2. if k<key[x] then x ← lc[x]
3. else x ← rc[x]
4. return x
6 4
3
7
7 9
Baumsuche(root[T],5) x
68
Ein Datenbank-Problem
4
IterativeBaumsuche(x,k)
1. while x≠nil and k≠key[x] do 2. if k<key[x] then x ← lc[x]
3. else x ← rc[x]
4. return x
6
3
7
7 9
Baumsuche(root[T],5)
x nil
69
Ein Datenbank-Problem
IterativeBaumsuche(x,k)
1. while x≠nil and k≠key[x] do 2. if k<key[x] then x ← lc[x]
3. else x ← rc[x]
4. return x
4
6
3
7
7 9
Baumsuche(root[T],5)
x nil
70
Ein Datenbank-Problem
IterativeBaumsuche(x,k)
1. while x≠nil and k≠key[x] do 2. if k<key[x] then x ← lc[x]
3. else x ← rc[x]
4. return x
4
6
3
7
7 9
Baumsuche(root[T],5)
x nil
IterativeBaumsuche(x,k)
1. while x≠nil and k≠key[x] do 2. if k<key[x] then x ← lc[x]
3. else x ← rc[x]
4. return x
4
Ein Datenbank-Problem
6
3
7
7 9
Funktionsweise wie (rekursive) Baumsuche. Laufzeit ebenfalls
O(h).
71
72
Ein Datenbank-Problem
Weitere Operationen in Binärbäumen
• Minimumsuche
• Maximumsuche
• Vorgängersuche
• Nachfolgersuche
6 4
3
7
7 9
73
Ein Datenbank-Problem
Minimum- und Maximumsuche:
• Suchbaumeigenschaft:
Alle Knoten im rechten Unterbaum eines Knotens x sind größer gleich key[x]
• Alle Knoten im linken Unterbaum von x sind ≤ key[x]
6 4
3
7
7 9
74
Ein Datenbank-Problem
MinimumSuche(x)
1. while lc[x]≠nil do x ← lc[x]
2. return x
6 4
3
7
7 9
75
Ein Datenbank-Problem
MinimumSuche(x)
1. while lc[x]≠nil do x ← lc[x]
2. return x
6 4
3
7
7 9
x
76
Ein Datenbank-Problem
MinimumSuche(x)
1. while lc[x]≠nil do x ← lc[x]
2. return x
6 4
3
7
7 9
x
77
Ein Datenbank-Problem
MinimumSuche(x)
1. while lc[x]≠nil do x ← lc[x]
2. return x
6 4
3
7
7 9
x
78
Ein Datenbank-Problem
MinimumSuche(x)
1. while lc[x]≠nil do x ← lc[x]
2. return x
6 4
3
7
7 9
x
Laufzeit O(h)
79
Ein Datenbank-Problem
MaximumSuche(x)
1. while rc[x]≠nil do x ← rc[x]
2. return x
6 4
3
7
7 9
x
80
Ein Datenbank-Problem
MaximumSuche(x)
1. while rc[x]≠nil do x ← rc[x]
2. return x
6 4
3
7
7 9
x
81
Ein Datenbank-Problem
MaximumSuche(x)
1. while rc[x]≠nil do x ← rc[x]
2. return x
6 4
3
7
7 9
x
82
Ein Datenbank-Problem
MaximumSuche(x)
1. while rc[x]≠nil do x ← rc[x]
2. return x
6 4
3
7
7 9
x
83
Ein Datenbank-Problem
MaximumSuche(x)
1. while rc[x]≠nil do x ← rc[x]
2. return x
6 4
3
7
7 9
x
84
Ein Datenbank-Problem
MaximumSuche(x)
1. while rc[x]≠nil do x ← rc[x]
2. return x
Laufzeit O(h)
6 4
3
7
7 9
x
85
Ein Datenbank-Problem
MaximumSuche(x)
1. while rc[x]≠nil do x ← rc[x]
2. return x
Laufzeit O(h)
6 4
3
7
7 9
x
86
Ein Datenbank-Problem
Nachfolgersuche:
• Nachfolger bzgl. Inorder-Tree-Walk
• Wenn alle Schlüssel unterschiedlich, dann ist das der nächstgrößere Schlüssel
6 4
3
7
7 9
87
Ein Datenbank-Problem
Nachfolgersuche:
• Fall 1 (rechter Unterbaum von x nicht leer):
Dann ist der linkeste Knoten im rechten Unterbaum der Nachfolger von x
6 4
3
7
7 9
88
Ein Datenbank-Problem
Nachfolgersuche:
• Fall 1 (rechter Unterbaum von x nicht leer):
Dann ist der linkeste Knoten im rechten Unterbaum der Nachfolger von x
6 4
3
7
7 9
89
Ein Datenbank-Problem
Nachfolgersuche:
• Fall 1 (rechter Unterbaum von x nicht leer):
Dann ist der linkeste Knoten im rechten Unterbaum der Nachfolger von x
6 4
3
7
7 9
90
Ein Datenbank-Problem
Nachfolgersuche:
• Fall 2 (rechter Unterbaum von x leer und x hat Nachfolger y):
Dann ist y der niedrigste Vorgänger von x, dessen linkes Kind ebenfalls Nachfolger von x ist
6 4
3
7
5 9
91
Ein Datenbank-Problem
Nachfolgersuche:
• Fall 2 (rechter Unterbaum von x leer und x hat Nachfolger y):
Dann ist y der niedrigste Vorgänger von x, dessen linkes Kind ebenfalls Nachfolger von x ist
6 4
3
7
5 9
92
Ein Datenbank-Problem
Nachfolgersuche:
• Fall 2 (rechter Unterbaum von x leer und x hat Nachfolger y):
Dann ist y der niedrigste Vorgänger von x, dessen linkes Kind ebenfalls Nachfolger von x ist
6 4
3
7
5 9
93
Ein Datenbank-Problem
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 4. x ← y
5. y ← p[y]
6. return y 6
4 3
7
5 9
94
Ein Datenbank-Problem
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 4. x ← y
5. y ← p[y]
6. return y 6
4 3
7
5 9
Nachfolgersuche(6)
95
Ein Datenbank-Problem
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 4. x ← y
5. y ← p[y]
6. return y 6
4 3
7
5 9
Nachfolgersuche(6)
96
Ein Datenbank-Problem
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 4. x ← y
5. y ← p[y]
6. return y 6
4 3
7
5 9
Nachfolgersuche(6)
97
Ein Datenbank-Problem
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 4. x ← y
5. y ← p[y]
6. return y 6
4 3
7
5 9
Nachfolgersuche(5)
98
Ein Datenbank-Problem
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 4. x ← y
5. y ← p[y]
6. return y 6
4 3
7
5 9
Nachfolgersuche(5)
99
Ein Datenbank-Problem
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 4. x ← y
5. y ← p[y]
6. return y 6
4 3
7
5 9
Nachfolgersuche(5) y
100
Ein Datenbank-Problem
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 4. x ← y
5. y ← p[y]
6. return y 6
4 3
7
5 9
Nachfolgersuche(5) y
x
101
Ein Datenbank-Problem
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 4. x ← y
5. y ← p[y]
6. return y 6
4 3
7
5 9
Nachfolgersuche(5)
y x
102
Ein Datenbank-Problem
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 4. x ← y
5. y ← p[y]
6. return y 6
4 3
7
5 9
Nachfolgersuche(5) y
x
103
Ein Datenbank-Problem
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 4. x ← y
5. y ← p[y]
6. return y 6
4 3
7
5 9
Nachfolgersuche(5) y
x
104
Ein Datenbank-Problem
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 4. x ← y
5. y ← p[y]
6. return y 6
4 3
7
5 9
Nachfolgersuche(5) y
105
Ein Datenbank-Problem
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 4. x ← y
5. y ← p[y]
6. return y
Laufzeit O(h)
6 4
3
7
5 9
106
Ein Datenbank-Problem
Vorgängersuche:
• Symmetrisch zu Nachfolgersuche
• Daher ebenfall O(h) Laufzeit
6 4
3
7
5 9
107
Ein Datenbank-Problem
Binäre Suchbäume:
• Aufzähler der Elemente mit Inorder-Tree-Walk in O(n) Zeit
• Such 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?
108
Ein Datenbank-Problem
Einfügen:
• Ähnlich wie Baumsuche: Finde Blatt, an das neuer Knoten angehängt wird
• Danach wird nil-Zeiger durch neues
Element ersetzt 6
4 3
7
5 9
109
Ein Datenbank-Problem
Einfügen(T,z)
1. y← nil; x ← root[T]
2. while x≠nil do 3. y ← x
4. if key[z] < key[x] then x ← lc[x]
5. else x ← rc[x]
6. p[z] ← y
7. if y=nil then root[T] ← z 8. else
9. if key[z]< key[y] then lc[y] ← z 10. else rc[y] ← z
6 4
3
7
5 9
110
Ein Datenbank-Problem
Einfügen(T,z)
1. y← nil; x ← root[T]
2. while x≠nil do 3. y ← x
4. if key[z] < key[x] then x ← lc[x]
5. else x ← rc[x]
6. p[z] ← y
7. if y=nil then root[T] ← z 8. else
9. if key[z]< key[y] then lc[y] ← z 10. else rc[y] ← z
6 4
3
7
5 9
Einfügen(8)
y ist Vater des einzufügenden
Elements
x
111
Ein Datenbank-Problem
Einfügen(T,z)
1. y← nil; x ← root[T]
2. while x≠nil do 3. y ← x
4. if key[z] < key[x] then x ← lc[x]
5. else x ← rc[x]
6. p[z] ← y
7. if y=nil then root[T] ← z 8. else
9. if key[z]< key[y] then lc[y] ← z 10. else rc[y] ← z
6 4
3
7
5 9
Einfügen(8) x
112
Ein Datenbank-Problem
Einfügen(T,z)
1. y← nil; x ← root[T]
2. while x≠nil do 3. y ← x
4. if key[z] < key[x] then x ← lc[x]
5. else x ← rc[x]
6. p[z] ← y
7. if y=nil then root[T] ← z 8. else
9. if key[z]< key[y] then lc[y] ← z 10. else rc[y] ← z
6 4
3
7
5 9
Einfügen(8)
x y
113
Ein Datenbank-Problem
Einfügen(T,z)
1. y← nil; x ← root[T]
2. while x≠nil do 3. y ← x
4. if key[z] < key[x] then x ← lc[x]
5. else x ← rc[x]
6. p[z] ← y
7. if y=nil then root[T] ← z 8. else
9. if key[z]< key[y] then lc[y] ← z 10. else rc[y] ← z
6 4
3
7
5 9
Einfügen(8)
x y
114
Ein Datenbank-Problem
Einfügen(T,z)
1. y← nil; x ← root[T]
2. while x≠nil do 3. y ← x
4. if key[z] < key[x] then x ← lc[x]
5. else x ← rc[x]
6. p[z] ← y
7. if y=nil then root[T] ← z 8. else
9. if key[z]< key[y] then lc[y] ← z 10. else rc[y] ← z
6 4
3
7
5 9
Einfügen(8) y
x
115
Ein Datenbank-Problem
Einfügen(T,z)
1. y← nil; x ← root[T]
2. while x≠nil do 3. y ← x
4. if key[z] < key[x] then x ← lc[x]
5. else x ← rc[x]
6. p[z] ← y
7. if y=nil then root[T] ← z 8. else
9. if key[z]< key[y] then lc[y] ← z 10. else rc[y] ← z
6 4
3
7
5 9
Einfügen(8)
x y
116
Ein Datenbank-Problem
Einfügen(T,z)
1. y← nil; x ← root[T]
2. while x≠nil do 3. y ← x
4. if key[z] < key[x] then x ← lc[x]
5. else x ← rc[x]
6. p[z] ← y
7. if y=nil then root[T] ← z 8. else
9. if key[z]< key[y] then lc[y] ← z 10. else rc[y] ← z
6 4
3
7
5 9
Einfügen(8)
x y
117
Ein Datenbank-Problem
Einfügen(T,z)
1. y← nil; x ← root[T]
2. while x≠nil do 3. y ← x
4. if key[z] < key[x] then x ← lc[x]
5. else x ← rc[x]
6. p[z] ← y
7. if y=nil then root[T] ← z 8. else
9. if key[z]< key[y] then lc[y] ← z 10. else rc[y] ← z
6 4
3
7
5 9
Einfügen(8)
x y
118
Ein Datenbank-Problem
Einfügen(T,z)
1. y← nil; x ← root[T]
2. while x≠nil do 3. y ← x
4. if key[z] < key[x] then x ← lc[x]
5. else x ← rc[x]
6. p[z] ← y
7. if y=nil then root[T] ← z 8. else
9. if key[z]< key[y] then lc[y] ← z 10. else rc[y] ← z
6 4
3
7
5 9
Einfügen(8)
y x
119
Ein Datenbank-Problem
Einfügen(T,z)
1. y← nil; x ← root[T]
2. while x≠nil do 3. y ← x
4. if key[z] < key[x] then x ← lc[x]
5. else x ← rc[x]
6. p[z] ← y
7. if y=nil then root[T] ← z 8. else
9. if key[z]< key[y] then lc[y] ← z 10. else rc[y] ← z
6 4
3
7
5 9
Einfügen(8)
y x
120
Ein Datenbank-Problem
Einfügen(T,z)
1. y← nil; x ← root[T]
2. while x≠nil do 3. y ← x
4. if key[z] < key[x] then x ← lc[x]
5. else x ← rc[x]
6. p[z] ← y
7. if y=nil then root[T] ← z 8. else
9. if key[z]< key[y] then lc[y] ← z 10. else rc[y] ← z
6 4
3
7
5 9
Einfügen(8)
y x
121
Ein Datenbank-Problem
Einfügen(T,z)
1. y← nil; x ← root[T]
2. while x≠nil do 3. y ← x
4. if key[z] < key[x] then x ← lc[x]
5. else x ← rc[x]
6. p[z] ← y
7. if y=nil then root[T] ← z 8. else
9. if key[z]< key[y] then lc[y] ← z 10. else rc[y] ← z
6 4
3
7
5 9
Einfügen(8)
y x nil
122
Ein Datenbank-Problem
Einfügen(T,z)
1. y← nil; x ← root[T]
2. while x≠nil do 3. y ← x
4. if key[z] < key[x] then x ← lc[x]
5. else x ← rc[x]
6. p[z] ← y
7. if y=nil then root[T] ← z 8. else
9. if key[z]< key[y] then lc[y] ← z 10. else rc[y] ← z
6 4
3
7
5 9
Einfügen(8)
y x nil
123
Ein Datenbank-Problem
Einfügen(T,z)
1. y← nil; x ← root[T]
2. while x≠nil do 3. y ← x
4. if key[z] < key[x] then x ← lc[x]
5. else x ← rc[x]
6. p[z] ← y
7. if y=nil then root[T] ← z 8. else
9. if key[z]< key[y] then lc[y] ← z 10. else rc[y] ← z
6 4
3
7
5 9
Einfügen(8)
y x nil
124
Ein Datenbank-Problem
Einfügen(T,z)
1. y← nil; x ← root[T]
2. while x≠nil do 3. y ← x
4. if key[z] < key[x] then x ← lc[x]
5. else x ← rc[x]
6. p[z] ← y
7. if y=nil then root[T] ← z 8. else
9. if key[z]< key[y] then lc[y] ← z 10. else rc[y] ← z
6 4
3
7
5 9
Einfügen(8)
y x nil
125
Ein Datenbank-Problem
Einfügen(T,z)
1. y← nil; x ← root[T]
2. while x≠nil do 3. y ← x
4. if key[z] < key[x] then x ← lc[x]
5. else x ← rc[x]
6. p[z] ← y
7. if y=nil then root[T] ← z 8. else
9. if key[z]< key[y] then lc[y] ← z 10. else rc[y] ← z
6 4
3
7
5 9
Einfügen(8)
y x 8
126
Ein Datenbank-Problem
Einfügen(T,z)
1. y← nil; x ← root[T]
2. while x≠nil do 3. y ← x
4. if key[z] < key[x] then x ← lc[x]
5. else x ← rc[x]
6. p[z] ← y
7. if y=nil then root[T] ← z 8. else
9. if key[z]< key[y] then lc[y] ← z 10. else rc[y] ← z
Einfügen(8)
6 4
3
7
5 9 y
x 8
127
Ein Datenbank-Problem
Einfügen(T,z)
1. y← nil; x ← root[T]
2. while x≠nil do 3. y ← x
4. if key[z] < key[x] then x ← lc[x]
5. else x ← rc[x]
6. p[z] ← y
7. if y=nil then root[T] ← z 8. else
9. if key[z]< key[y] then lc[y] ← z 10. else rc[y] ← z
Einfügen(8)
6 4
3
7
5 9 y
Laufzeit:
x 8 O(h)128
Ein Datenbank-Problem
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 3
7
5 9
129
Ein Datenbank-Problem
Fall (a):
• zu löschendes Element z hat keine Kinder
6 4
3
7
5 9
130
Ein Datenbank-Problem
Fall (a):
• zu löschendes Element z hat keine Kinder
• Entferne Element
6 4
3
7
5 9
6 4
3
7
9
131
Ein Datenbank-Problem
Fall (b):
• zu löschendes Element z hat ein Kind
6 4
3
7
5 9
132
Ein Datenbank-Problem
Fall (b):
• zu löschendes Element z hat ein Kind
• Hänge der Unterbaum von z an den Vater von z
6 4
3
7
5 9
6 4
3
9 5
133
Ein Datenbank-Problem
Fall (c):
• zu löschendes Element z hat zwei Kinder
6 4
3
7
5 9
134
Ein Datenbank-Problem
Fall (c):
• zu löschendes Element z hat zwei Kinder
• Schritt 1: Bestimme Nachfolger von z
6 4
3
7
5 9
135
Ein Datenbank-Problem
Fall (c):
• zu löschendes Element z hat zwei Kinder
• Schritt 1: Bestimme Nachfolger von z
• Schritt 2: Entferne Nachfolger
6 4
3
7
5 9
6 4
3
9 5
136
Ein Datenbank-Problem
Fall (c):
• zu löschendes Element z hat zwei Kinder
• Schritt 1: Bestimme Nachfolger von z
• Schritt 2: Entferne Nachfolger
6 4
3
7
5 9
6 4
3
9 5
Nachfolger hat nur ein Kind!
137
Ein Datenbank-Problem
Fall (c):
• zu löschendes Element z hat zwei Kinder
• Schritt 1: Bestimme Nachfolger von z
• Schritt 2: Entferne Nachfolger
6 4
3
7
5 9
6 4
3
9 5
138
Ein Datenbank-Problem
Fall (c):
• zu löschendes Element z hat zwei Kinder
• Schritt 1: Bestimme Nachfolger von z
• Schritt 2: Entferne Nachfolger
• Schritt 3: Ersetze z durch entfernten Nachfolger 6
4 3
7
5 9
7 4
3
9 5
139
Ein Datenbank-Problem
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 8. else rc[p[y]] ← x
9. if y ≠ z then key[z] ← key[y]
10. return y
6 4
3
7
5 9
140
Ein Datenbank-Problem
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 8. else rc[p[y]] ← x
9. if y ≠ z then key[z] ← key[y]
10. return y
Löschen(6) 6
4 3
7
5 9
141
Ein Datenbank-Problem
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 8. else rc[p[y]] ← x
9. if y ≠ z then key[z] ← key[y]
10. return y
6 4
3
7
5 9
Löschen(6)
142
Ein Datenbank-Problem
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 8. else rc[p[y]] ← x
9. if y ≠ z then key[z] ← key[y]
10. return y
Bestimme Knoten, der gelöscht werden soll.
Der Knoten hat nur einen Nachfolger
6 4
3
7
5 9
z
Löschen(6)
143
Ein Datenbank-Problem
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 8. else rc[p[y]] ← x
9. if y ≠ z then key[z] ← key[y]
10. return y
Bestimme Knoten, der gelöscht werden soll.
Der Knoten hat nur einen Nachfolger
6 4
3
7
5 9
z
Löschen(6)
y
144
Ein Datenbank-Problem
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 8. else rc[p[y]] ← x
9. if y ≠ z then key[z] ← key[y]
10. return y
Bestimme den Nachfolger von y (falls
dieser existiert).
6 4
3
7
5 9
z
Löschen(6)
y x
145
Ein Datenbank-Problem
Löschen(6)
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 8. else rc[p[y]] ← x
9. if y ≠ z then key[z] ← key[y]
10. return y
Aktualisiere Vaterzeiger von x
6 4
3
7
5 9
z
y x
146
Ein Datenbank-Problem
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 8. else rc[p[y]] ← x
9. if y ≠ z then key[z] ← key[y]
10. return y
Löschen(6) 6
4 3
7
5 9
z
y x