NIL.parent

Werbung
Informatik II - SS 2016
(Algorithmen & Datenstrukturen)
Vorlesung 11 (1.6.2016)
Binäre Suchbäume III
Fabian Kuhn
Algorithmen und Komplexität
Fabian Kuhn
Informatik II, SS 2016
Tiefe eines binären Suchbaums
Worst-Case Laufzeit der Operationen in binären Suchbäumen:
๐‘ถ(๐“๐ข๐ž๐Ÿ๐ž ๐๐ž๐ฌ ๐๐š๐ฎ๐ฆ๐ฌ)
• Im besten Fall ist die Tiefe ๐ฅ๐จ๐  ๐Ÿ ๐’
– Definition Tiefe: Länge des längsten Pfades von der Wurzel zu einem Blatt
• Im schlechtesten Fall ist die Tiefe ๐’ − ๐Ÿ
Was ist die Tiefe in einem typischen Fall?
• Was ist ein typischer Fall?
Ist es möglich, in einem binären Suchbaum immer Tiefe ๐‘‚ log ๐‘› zu
garantieren?
Fabian Kuhn
Informatik II, SS 2016
2
“Typischer” Fall
Zufälliger binärer Suchbaum:
• ๐’ Schlüssel werden in zufälliger Reihenfolge eingefügt
Beobachtung:
• Mit Wahrscheinlichkeit 1Τ3 haben beide Teilbäume der Wurzel
mindestens ๐‘›Τ3 Knoten.
• Analoges gilt auch für alle Teilbäume
• Im Durchschnitt wird deshalb auf jedem 3. Schritt von der Wurzel
Richtung eines Blattes, der Teilbaum um einen Faktor 2Τ3 kleiner!
• Verkleinern um einen Faktor 2Τ3 geht nur ๐‘‚ log ๐‘› oft.
• Tiefe eines zufälligen binären Suchbaums ist deshalb ๐‘‚ log ๐‘›
• Genaue Rechnung ergibt:
Erwartete Tiefe eines zufälligen bin. Suchbaums: ๐Ÿ’. ๐Ÿ‘๐Ÿ๐Ÿ ⋅ ๐ฅ๐ง ๐’
Fabian Kuhn
Informatik II, SS 2016
3
“Typischen” Fall erzwingen?
“Typischer” Fall:
• Falls die Schlüssel in zufälliger Reihenfolge eingefügt werden, hat
der Baum Tiefe ๐‘‚ log ๐‘›
• Operationen haben Laufzeit ๐‘‚(log ๐‘›)
Problem:
• Zufällige Reihenfolge ist nicht unbedingt der typische Fall!
• Vorsortierte Werte kann genau so typisch sein
– Das ergibt einen sehr schlechten binären Suchbaum
Idee:
• Können wir zufällige Reihenfolge erzwingen?
• Schlüssel werden in beliebiger Reihenfolge eingefügt, aber
Struktur soll immer wie bei zufälliger Reihenfolge sein!
Fabian Kuhn
Informatik II, SS 2016
4
Heap
Heap (Min-Heap) Eigenschaft:
• Gegeben ein Baum, jeder Knoten einen Schlüssel
• Ein Baum hat die Min-Heap Eigenschaft, falls in jedem Teilbaum,
die Wurzel den kleinsten Schlüssel hat
• Heaps sind auch die “richtige” Datenstruktur, um
Prioritätswarteschlangen zu implementieren
– werden wir noch behandeln
Fabian Kuhn
Informatik II, SS 2016
5
Kombination Binary Search Tree / Heap
Annahme:
• Jedes Element hat zwei eindeutige Schlüssel key1 und key2
Ziel:
• Binärer Suchbaum bezüglich key1
• Einfügen in Reihenfolge, welche durch key2 gegeben ist
Beispiel: 1,4 , 2,7 , 3,1 , 4,10 , 5,3 , 6,8 , 7,9 , 8,2 , 9,6 , (10,5)
Fabian Kuhn
Informatik II, SS 2016
6
Treap: Kombination BST / Heap
Annahme:
• Jedes Element hat zwei eindeutige Schlüssel key1 und key2
Treap:
• Binärer Suchbaum bezüglich key1
• Min-Heap bezüglich key2
• Entspricht bin. Suchbaum der Schlüssel key1, in welchen die
Schlüssel in der durch key2 geg. Reihenfolge eingefügt wurden
Ziel:
• Zu jedem Primärschlüssel (key1) wird zusätzlich ein zufälliger
Schlüssel key2 ∈ [0,1] bestimmt
• Stelle bei jedem insert / delete sicher, dass der Baum ein Treap
beüglich der Schlüssel key1 und key2 ist!
• Enspricht bin. Suchbaum mit zufälliger Einfügereihenfolge
Fabian Kuhn
Informatik II, SS 2016
7
Treap: Einfügen und Löschen
• Einfügen und Löschen funktioniert erstmal gleich, wie bei einem
normalen binären Suchbaum
• Allerdings kann dann allenfalls die Min-Heap-Eigenschaft bezüglich
key2 nicht mehr erfüllt sein
• Beispiel: insert(๐ŸŽ, 0.35), delete(๐Ÿ•)
๐Ÿ“, 0.13
๐Ÿ‘, 0.22
๐Ÿ, 0.47
๐Ÿ•, 0.32
๐Ÿ”, 0.39
๐Ÿ, 0.81
Fabian Kuhn
๐Ÿ—, 0.82
๐Ÿ–, 0.90
Informatik II, SS 2016
8
Sentinel
Um den Code zu vereinfachen…
Sentinel-Knoten: NIL
• Ersetzt alle None(null)-Pointer
• NIL.key1 ist nicht definiert (wird nie gesetzt oder gelesen)
• NIL.key2 = -1.0 (und damit immer kleiner als alle anderen)
– wird nie verändert
• NIL.left, NIL.right, NIL.parent können beliebig gesetzt sein
– Wir müssen darau achten, dass sie nie ausgelesen werden
– Wenn es den Code vereinfacht, kann man NIL.parent, ... neu setzen
Fabian Kuhn
Informatik II, SS 2016
9
Rotationen
• Rechtsrotation
๐Ÿ•, 0.23
๐Ÿ—, 0.32
๐Ÿ’, 0.19
๐Ÿ, 0.82
Fabian Kuhn
๐Ÿ’, 0.19
๐Ÿ, 0.82
๐Ÿ“, 0.90
๐Ÿ•, 0.23
๐Ÿ“, 0.90
Informatik II, SS 2016
๐Ÿ—, 0.32
10
Rotationen
• Linksrotation
๐Ÿ“, 0.23
๐Ÿ’, 0.32
๐Ÿ–, 0.19
๐Ÿ”, 0.90
Fabian Kuhn
๐Ÿ–, 0.19
๐Ÿ—, 0.82
๐Ÿ“, 0.23
๐Ÿ—, 0.82
๐Ÿ’, 0.32
Informatik II, SS 2016
๐Ÿ”, 0.90
11
Rechtsrotation
๐’–
right-rotate(u,v):
๐’—
u.left = v.right
u.left.parent = u
if u == root then
root = v
else
if u == u.parent.left then
u.parent.left = v
else
u.parent.right = v
v.parent = u.parent
v.right = u
u.parent = v
Fabian Kuhn
Informatik II, SS 2016
๐’—
๐’–
12
Linksrotation
๐’—
left-rotate(u,v):
u.right = v.left
๐’–
u.right.parent = u
if u == root then
root = v
else
if u == u.parent.left then
u.parent.left = v
else
u.parent.right = v
v.parent = u.parent
v.left = u
u.parent = v
Fabian Kuhn
Informatik II, SS 2016
๐’–
๐’—
13
Korrektheit: Rotationen
Lemma: Rotationen erhalten die “Bin. Search Tree”-Eigenschaft
๐’–
๐’„
๐’—
๐’‚
Fabian Kuhn
Informatik II, SS 2016
๐’—
๐’ƒ
๐’‚
๐’–
๐’ƒ
๐’„
14
Treap: Einfügen
• Beispiel: insert(๐ŸŽ, 0.15)
๐Ÿ“, 0.13
๐Ÿ‘, 0.22
๐Ÿ, 0.47
๐ŸŽ, 0.15
๐Ÿ•, 0.32
๐Ÿ’, 0.39
๐Ÿ, 0.81
๐Ÿ—, 0.82
๐Ÿ–, 0.90
๐Ÿ“, 0.13
๐Ÿ“, 0.13
๐Ÿ‘, 0.22
๐ŸŽ, 0.15
๐ŸŽ, 0.15
๐Ÿ•, 0.32
๐Ÿ’, 0.39
๐Ÿ, 0.47
๐Ÿ—, 0.82
๐Ÿ’, 0.39
๐Ÿ—, 0.82
๐Ÿ–, 0.90
๐Ÿ, 0.81
๐Ÿ, 0.81
Fabian Kuhn
๐Ÿ‘, 0.22
๐Ÿ, 0.47
๐Ÿ–, 0.90
๐Ÿ•, 0.32
Informatik II, SS 2016
15
Treap: Einfügen
Ziel: Füge Schlüssel ๐‘ฅ ein
1. Bestimme zufälligen zweiten Schlüssel ๐‘ฆ
2. Füge (๐‘ฅ, ๐‘ฆ) wie üblich in den bin. Suchbaum (bez. ๐‘ฅ) ein
3. Annahme:
Knoten mit Schlüssel ๐‘ฅ heisst ๐‘ฃ,
๐‘ข = ๐‘ฃ. parent
while v.key2 < u.key2 do
if v == u.left then
right-rotate(u,v)
else
left-rotate(u,v)
u = v.parent
Fabian Kuhn
Informatik II, SS 2016
16
Treap insert(x)
// assumption: treap is not empty
w.key1
v = root; y = random(0,1)
w.key2
while v != NIL and v.key1 != x do
w.parent
if v.key1 > v.x then
w.left w.right
if v.left == NIL then
w = new TreeNode(x,y,v,NIL,NIL); v.left = w
v = v.left
else
if v.right == NIL then
w = new TreeNode(x,y,v,NIL,NIL); v.right = w
v = v.right
// v now is the node with v.key1 == x
u = v.parent
while v.key2 < u.key2 do
if v == u.left then
right-rotate(u,v)
else
left-rotate(u,v)
u = v.parent
Fabian Kuhn
Informatik II, SS 2016
17
Treap: Einfügen, Korrektheit
Lemma: Der Treap ist zu jeder Zeit während dem Einfügen von ๐‘ฅ
ein korrekter binärer Suchbaum bezügl. key1
Beweis:
• Der neue Knoten wird am Anfang wie bisher eingefügt
– da, wo man bei der Suche nach ๐‘ฅ auf NIL trifft
• Rotationen erhalten die BST-Eigenschaft
Fabian Kuhn
Informatik II, SS 2016
18
Treap: Terminierung
Annahme: Nach dem Einflügen von ๐‘ฅ ist der Schlüssel ๐‘ฅ im
Knoten ๐‘ฃ gespeichert und der Pfad von der Wurzel zu ๐‘ฃ ist:
๐‘Ÿ๐‘œ๐‘œ๐‘ก = ๐‘ข1 , ๐‘ข2 , … , ๐‘ข๐‘˜ , ๐‘ฃ
Lemma: Nach ๐‘– ≤ ๐‘˜ Rotationen ist der Pfad von der Wurzel zu ๐‘ฃ
๐‘Ÿ๐‘œ๐‘œ๐‘ก = ๐‘ข1 , ๐‘ข2 , … , ๐‘ข๐‘˜−๐‘– , ๐‘ฃ
Beweis: Per Induktion (für alle ๐‘– = 0, … , ๐‘˜)
• Verankerung ๐‘– = 0
• Induktionsschritt:
Korollar: Alg. terminiert nach ≤ ๐‘˜ Rotationen
Fabian Kuhn
Informatik II, SS 2016
19
Treap: Heap-Eigenschaft
Lemma: Nach ๐‘– ≤ ๐‘˜ Rotationen:
1) Pfad von der Wurzel zu ๐‘ฃ: ๐‘Ÿ๐‘œ๐‘œ๐‘ก = ๐‘ข1 , ๐‘ข2 , … , ๐‘ข๐‘˜−๐‘– , ๐‘ฃ
2) Teilbäume aller Knoten ๐‘ค ≠ ๐‘ข1 , … , ๐‘ข๐‘˜−๐‘– erfüllen Heap-Eigenschaft
3) Für alle Knoten ๐‘ข๐‘— , ๐‘— ∈ 1, … , ๐‘˜ − ๐‘– und alle Knoten ๐‘ค ≠ ๐‘ฃ im
Teilbaum von ๐‘ข๐‘— gilt: ๐‘ข๐‘— .key2 ≤ ๐‘ค.key2
Beweis: Induktion (für alle ๐‘– = 0, … , ๐‘˜)
• Verankerung:
Fabian Kuhn
Informatik II, SS 2016
20
Treap: Heap-Eigenschaft
Lemma: Nach ๐‘– ≤ ๐‘˜ Rotationen:
1) Pfad von der Wurzel zu ๐‘ฃ: ๐‘Ÿ๐‘œ๐‘œ๐‘ก = ๐‘ข1 , ๐‘ข2 , … , ๐‘ข๐‘˜−๐‘– , ๐‘ฃ
2) Teilbäume aller Knoten ๐‘ค ≠ ๐‘ข1 , … , ๐‘ข๐‘˜−๐‘– erfüllen Heap-Eigenschaft
3) Für ๐‘ข๐‘— , ๐‘— ∈ 1, … , ๐‘˜ − ๐‘– und ๐‘ค ≠ ๐‘ฃ im Teilbaum von ๐‘ข๐‘— gilt: ๐‘ข๐‘— .key2 ≤ ๐‘ค.key2
Beweis: Induktion (für alle ๐‘– = 0, … , ๐‘˜)
• Induktionsschritt:
Fabian Kuhn
Informatik II, SS 2016
21
Treap: Einfügen
Theorem: Beim Einfügen eines Schlüssels bleibt die Treap-Eigenschaft
erhalten. Laufzeit des Einfügens: ๐‘‚(Tiefe) des Baums
Korollar: Einfügen hat mit hoher Wahrscheinlichkeit Laufzeit ๐‘‚ log ๐‘› .
Fabian Kuhn
Informatik II, SS 2016
22
Treap: Löschen
Ziel: Lösche Schlüssel ๐‘ฅ
1. Suche Knoten ๐‘ฃ mit Schlüssel ๐‘ฅ
2. Solange ๐‘ฃ zwei Kinder hat:
โ€’
โ€’
โ€’
๐‘ค ist das Kind mit kleinerem key2
Falls ๐‘ค == ๐‘ฃ. left, dann mache Rechtsrot.: right-rotate(v,w)
Falls ๐‘ค == ๐‘ฃ. right, dann mache Linksrot.: left-rotate(v,w)
3. Lösche ๐‘ฃ
โ€’
Fabian Kuhn
๐‘ฃ hat höchstens ein Kind und kann daher einfach gelöscht warden
(ohne die min-heap Eigenschaft zu verletzen)
Informatik II, SS 2016
23
Treap: Eigenschaften
• Zwei Schlüssel key1 und key2
– key1 ist der normale Schlüssel für die Dictionary-Operationen
– key2 ist ein zufälliger Schlüssel, um den Baum balanciert zu halten
• Immer ein bin. Suchbaum bez. key1 und ein Min-Heap bez. key2
Solange key2 unabhängig von allen insert/delete-Operationen gewählt
wird, hat der Baum immer die Struktur eines binären Suchbaums mit
zufälliger Einfügereihenfolge.
• Mit hoher Wahrscheinlichkeit: ๐“๐ข๐ž๐Ÿ๐ž ∈ ๐šฏ ๐ฅ๐จ๐  ๐’
Die Operationen find, insert, delete, min, max, succ, pred haben alle
Laufzeit ๐‘ถ(๐ฅ๐จ๐  ๐’)
• Wie man das auch deterministisch garantieren kann, werden
wir als nächstes sehen…
Fabian Kuhn
Informatik II, SS 2016
24
Rot-Schwarz-Bäume
Ziel: Binäre Suchbäume, welche immer balanciert sind
• balanciert, intuitiv: in jedem Teilbaum, links & rechts ≈ gleich gross
• balanciert, formal: Teilbaum mit ๐‘˜ Knoten hat Tiefe ๐‘‚ log ๐‘˜
Rot-Schwarz-Bäume sind binäre Suchbäume, für die gilt:
1) Alle Knoten sind rot oder schwarz
2) Wurzel ist schwarz
3) Blätter (= NIL-Knoten) sind schwarz
4) Rote Knoten haben zwei schwarze Kinder
5) Von jedem Knoten ๐‘ฃ aus, haben alle (direkten) Pfade zu Blättern
(NIL) im Teilbaum von ๐‘ฃ die gleiche Anzahl schwarze Knoten
Fabian Kuhn
Informatik II, SS 2016
25
Rot-Schwarz-Bäume: Beispiel
๐Ÿ๐Ÿ”
๐Ÿ๐Ÿ–
๐Ÿ’๐Ÿ‘
๐Ÿ๐Ÿ‘
๐Ÿ๐Ÿ
๐Ÿ‘๐Ÿ
๐Ÿ“๐Ÿ
NIL
๐Ÿ๐Ÿ•
๐Ÿ๐ŸŽ
๐Ÿ•
๐Ÿ“
NIL
๐Ÿ๐Ÿ
๐Ÿ๐Ÿ’
NIL NIL NIL NIL
NIL
๐Ÿ๐Ÿ’
๐Ÿ๐Ÿ—
NIL NIL
๐Ÿ๐ŸŽ
NIL
NIL
๐Ÿ๐Ÿ—
NIL NIL
NIL
NIL
๐Ÿ’๐ŸŽ
NIL
๐Ÿ‘๐Ÿ•
NIL
๐Ÿ’๐Ÿ
NIL NIL
NIL
NIL
Fabian Kuhn
Informatik II, SS 2016
26
Sentinel
Wie bei den Treaps, um den Code zu vereinfachen…
Sentinel-Knoten: NIL
• Ersetzt alle None/null-Pointer
• NIL.key ist nicht definiert (wird nie gesetzt oder gelesen)
• NIL.color = black
– Als Blätter des Baumes verstehen wir die NIL-Knoten (sind alle schwarz)
– repräsentiert alle Blätter des Baumes
• NIL.left, NIL.right, NIL.parent können beliebig gesetzt sein
– Wir müssen darauf achten, dass sie nie ausgelesen werden
– Wenn es den Code vereinfacht, kann man NIL.parent, ... neu setzen
Fabian Kuhn
Informatik II, SS 2016
27
Rot-Schwarz-Bäume: Sentinel
๐Ÿ๐Ÿ”
๐Ÿ๐Ÿ–
๐Ÿ’๐Ÿ‘
๐Ÿ๐Ÿ‘
๐Ÿ๐Ÿ
๐Ÿ๐Ÿ•
๐Ÿ๐ŸŽ
๐Ÿ•
๐Ÿ๐Ÿ
๐Ÿ๐Ÿ’
๐Ÿ‘๐Ÿ
๐Ÿ๐Ÿ’
๐Ÿ๐Ÿ—
๐Ÿ๐ŸŽ
๐Ÿ๐Ÿ—
๐Ÿ“๐Ÿ
๐Ÿ’๐ŸŽ
๐Ÿ‘๐Ÿ•
๐Ÿ’๐Ÿ
๐Ÿ“
NIL
Fabian Kuhn
Informatik II, SS 2016
28
Rot-Schwarz-Bäume: Repräsentation
๐Ÿ๐Ÿ”
๐Ÿ๐Ÿ–
๐Ÿ’๐Ÿ‘
๐Ÿ๐Ÿ‘
๐Ÿ๐Ÿ
๐Ÿ๐Ÿ•
๐Ÿ๐ŸŽ
๐Ÿ•
๐Ÿ๐Ÿ
๐Ÿ๐Ÿ’
๐Ÿ‘๐Ÿ
๐Ÿ๐Ÿ’
๐Ÿ๐Ÿ—
๐Ÿ๐ŸŽ
๐Ÿ๐Ÿ—
๐Ÿ“๐Ÿ
๐Ÿ’๐ŸŽ
๐Ÿ‘๐Ÿ•
๐Ÿ’๐Ÿ
๐Ÿ“
Fabian Kuhn
Informatik II, SS 2016
29
Tiefe / Schwarz-Tiefe
Definition: Die Tiefe (๐‘ป) eines Knoten ๐‘ฃ ist die maximale Länge eines
direkten Pfades von ๐‘ฃ zu einem Blatt (NIL).
Definition: Die Schwarz-Tiefe (๐‘บ๐‘ป) eines Knoten ๐‘ฃ ist die Anzahl schwarzer
Knoten auf jedem direkten Pfad von ๐‘ฃ zu einem Blatt (NIL)
• Der Knoten ๐‘ฃ wird dabei nicht gezählt, das Blatt (NIL, falls ≠ ๐‘ฃ) jedoch schon!
๐Ÿ๐Ÿ”
๐Ÿ๐Ÿ–
๐Ÿ’๐Ÿ‘
๐Ÿ๐Ÿ‘
๐Ÿ๐Ÿ
๐Ÿ‘๐Ÿ
๐Ÿ“๐Ÿ
NIL NIL
๐Ÿ๐Ÿ•
๐Ÿ๐ŸŽ
๐Ÿ•
๐Ÿ“
๐Ÿ๐Ÿ
๐Ÿ๐Ÿ’
NIL NIL NIL NIL NIL
๐Ÿ๐Ÿ’
๐Ÿ๐Ÿ—
NIL NIL
๐Ÿ๐ŸŽ
๐Ÿ๐Ÿ—
๐Ÿ’๐ŸŽ
NIL NIL NIL NIL
NIL NIL
๐Ÿ‘๐Ÿ•
๐Ÿ’๐Ÿ
NIL NIL NIL NIL
NIL NIL
Fabian Kuhn
Informatik II, SS 2016
30
Schwarz-Tiefe ↔ Anzahl Knoten
Lemma: Im Teilbaum eines Knoten ๐‘ฃ mit Schwarz-Tiefe ๐‘บ๐‘ป(๐’—) ist
die Anzahl innerer Knoten
≥ ๐Ÿ๐‘บ๐‘ป ๐’— − ๐Ÿ
Beweis:
• Per Induktion über die Tiefe ๐‘‡(๐‘ฃ) von ๐‘ฃ
Fabian Kuhn
Informatik II, SS 2016
31
Schwarz-Tiefe ↔ Anzahl Knoten
Lemma: Im Teilbaum eines Knoten ๐‘ฃ mit Schwarz-Tiefe ๐‘บ๐‘ป(๐’—) ist
die Anzahl innerer Knoten
≥ ๐Ÿ๐‘บ๐‘ป ๐’— − ๐Ÿ
Beweis:
• Per Induktion über die Tiefe ๐‘‡(๐‘ฃ) von ๐‘ฃ
Fabian Kuhn
Informatik II, SS 2016
32
Tiefe eins Rot-Schwarz-Baumes
Theorem:
Die Tiefe eines Rot-Schwarz-Baumes ist ≤ ๐Ÿ ๐ฅ๐จ๐  ๐Ÿ ๐’ + ๐Ÿ .
Beweis:
• Anzahl innerer Knoten : ๐‘› (alle ausser den NIL-Knoten)
• Lemma:
๐‘› ≥ 2๐‘†๐‘‡ ๐‘Ÿ๐‘œ๐‘œ๐‘ก − 1
Fabian Kuhn
Informatik II, SS 2016
33
Herunterladen