Grundzüge von Datenstrukturen und Algorithmen (WS 2013/2014

Werbung
Grundzüge von Datenstrukturen und Algorithmen
(WS 2013/2014)
Lösungsvorschlag zu Aufgabenblatt 5
Aufgabe 1
Idee
Wir nutzen, dass das Feld geordnet ist, indem wir ausgehend von der vermuteten Stelle f in
die richtige Richtung mit sich verdoppelnden Schrittweiten suchen, um das Intervall, indem
das Element liegen muss, einzugrenzen. Dann benötigen wir nur noch eine binr̈e Suche.
Algorithmus
finde(A, x,
wenn A[f]
wenn A[f]
wenn A[f]
f)
= x dann gib wahr zurueck
< x dann suche_rechts(A, x, f, 1)
> x dann suche_links(A, x, f, 1)
suche_rechts(A,x,f,schritt) //wir wissen: A[f] < x
i <- min(f + schritt, A.letzterIndex)
wenn A[i] = x dann gib wahr zurueck
wenn A[i] > x dann
gib das Ergebnis der binaere Suche nach x in A[f..i] zurueck
wenn A[i] < x und i < A.letzterIndex dann
gib das Ergebnis von suche_rechts(A,x,i, schritt * 2) zurueck
ansonsten gib falsch zurueck
suche_links(A,x,f,schritt) //wir wissen: A[f] > x
i <- max(f - schritt, 1)
wenn A[i] = x dann gib wahr zurueck
wenn A[i] < x dann
gib das Ergebnis der binaere Suche nach x in A[i..f] zurueck
wenn A[i] > x und i > 1 dann
gib das Ergebnis von suche_links(A,x,i, schritt * 2) zurueck
sonst gib falsch zurueck
Korrektheit
a) (x ∈ A)
Im trivialen Fall ist A[f ] = x und finde(A, x, f) gibt wahr zurück. Wir betrachten nun den
Fall, dass A[f ] < x und wir suche_rechts() ausführen (der andere Fall ergibt sich analog):
Es gilt A[f ] < x, da suche_rechts() immer nur dann aufgerufen wird, wenn diese Bedingung
eintritt. Es wird ein neues Element A[i] geprüft, dass eine gewisse Entfernung nach rechts
vom aktuellen f hat. Ist dieses das gewünschte x, geben wir korrekterweise wahr zurück. Gilt
dagegen A[i] > x, so ist A[f ] ≤ x ≤ A[i] und damit muss das z mit A[z] = x zwischen f und i
1
Grundzüge von Datenstrukturen und Algorithmen
(WS 2013/2014)
Lösungsvorschlag zu Aufgabenblatt 5
liegen. Führen wir eine binäre Suche in diesem Bereich durch, so finden wir x und geben wahr
zurück. Ist dagegen A[i] < x, so müssen wir weiter nach rechts suchen und werden x finden,
da spätestens wenn i = n der Fall A[i] ≤ x eintritt, der wie gezeigt korrekt behandelt wird.
b) (x ∈
/ A)
Wenn x kein Element von A ist, so können drei Fälle eintreten. Im ersten sind alle Elemente
in A kleiner als x. In diesem Fall wird suche_rechts() solange ausgeführt, bis i = n und kein
rekursiver Aufruf mehr erfolgt und es wird falsch zurückgegeben. Analog gibt suche_links()
falsch zurück, wenn i = 1 für den Fall, dass x kleiner ist als alle Elemente in A. Im letzten
Fall wird wie besprochen ein Intervall gefunden, in dem x liegen muss. Hat die binäre Suche
in diesem Intervall keinen Erfolg, so ist dieses Element nicht in A enthalten; es wird falsch
zurückgegeben.
Laufzeit
a)
Gilt für die tatsächliche Position z von x, dass z = x ± ∆, so benötigen wir einen Vergleich,
wenn ∆ = 0. Ansonsten sind höchstens (log ∆) + 1 Schritte nötig, um das Intervall einzugrenzen, da die Entfernung von der vermuteten Stelle in jedem Schritt mehr als verdoppelt
wird.
Das Intervall hat maximal eine Größe von ∆, denn spätestens sobald die Schrittweite so groß
ist, muss x in diesem neuen Bereich liegen, da bereits f ± schrittweite = z gilt. Damit ergibt
sich eine Laufzeit von O((log ∆) + 1 + log ∆) = O((log ∆) + 1).
b) Ist x ∈
/ A, so definiert sich das ∆ als Abstand von der vermuteten Stelle zur Position des
nächsten Elements, das größer (falls A[f ] < x) bzw. kleiner (wenn A[f ] > x) als x ist. Ist x
größer als jedes andere Element, so ist dies n − f . Ist x kleiner als alle Elemente in A, dann ist
∆ = f − 1. ∆ ist also der Abstand zu der Position, an der x stehen würde, wenn es enthalten
wäre.
Aufgabe 2
• Erinnerung: Der Nachfolger eines Knoten x ist der Knoten mit dem kleinsten Schlüssel
der größer als xs Schlüssel ist.
• Aufgrund der Eigenschaft binärer Suchbäume ist der Nachfolger y von x im rechten
Teilbaum von x (alle Schlüssel im linken Teilbaum sind kleiner als der von x)
• Da es keinen Schlüssel zwischen x und y gibt (sonst wäre y nicht der Nachfolger), gibt
es keinen Knoten in diesem Teilbaum, der kleiner als y ist
• Daher hat y einen leeren linken Teilbaum =⇒ y hat wenn überhaupt nur 1 Kind (falls
der rechte Teilbaum vorhanden ist)
2
Grundzüge von Datenstrukturen und Algorithmen
(WS 2013/2014)
Lösungsvorschlag zu Aufgabenblatt 5
Aufgabe 3
Für “Höhe eines Baumes” benutzen wir im Folgended die Definition “Höhe ist Anzahl Kanten
des Längsten Pfades”. Für die Definition mit “Knoten” anstatt Kanten ändern sich die Zahlen
nur etwas, der Beweis bleibt der gleiche.
Maximale Höhe
Der degenerierte binäre Suchbaum, bei dem jeder Knoten außer dem (einen) Blatt nur ein
Kind hat, hat Höhe n − 1. Er ensteht etwa, wenn n Knoten in aufsteigender Reihenfolge
eingefügt werden, da dann immer im rechten Teilbaum eingefügt wird.
Damit ein Suchbaum Höhe h haben kann, muss es mindestens einen Pfad dieser Länge geben.
Ein Pfad der Höhe h hat h + 1 Knoten. Somit kann es keinen Suchbaum mit Höhe ≥ n geben,
da sonst der “verursachende” Pfad > n Knoten hätte.
Somit ist die Höhe n − 1 maximal.
Minimale Höhe
Ein voller binärer Suchbaum der Tiefe h hat 2h − 1 Knoten (inklusive Blätter). Für einen
vollen binären Suchbaum mit n Knoten gilt also:
2h − 1 = n
⇐⇒
h = log2 (n + 1)
Ein balancierter Baum, dessen Pfadlängen sich maximal um 1 unterscheiden, hat > 2h−1 − 1
und ≤ 2h − 1 Blätter. Für einen balancierten Baum mit n Knoten gilt also:
⇐⇒
⇐⇒
2h−1 − 1 <
n
≤ 2h − 1
h−1
2
<
n+1
≤
2h
h−1
< log2 (n + 1) ≤
h
Eine geringere Höhe kann nicht erreicht werden, da dann eine dichtere Packung als beim vollen
binären Suchbaum gefunden wäre.
3
Herunterladen