Informatik I WS 05/06

Werbung
Informatik I WS 05/06
Prof. Dr. W. May
Dipl.-Inform. Oliver
Fritzen
Übungsblatt
11
Ausgegeben
am:
20.01.2006
Abgabe bis:
31.1.2006
(Theorie)
Dipl.-Inform. Christian
Kubczak
Thema: Algorithmen und Datenstrukturen: Bäume
Die Theorie-Aufgaben bearbeiten Sie bitte und werfen die Lösungen zum oben
genannten Termin in die Zettelkästen im Erdgeschoss der NAM. Eine Bearbeitung in
Zweier-Teams innerhalb Ihrer Übungsgruppe ist möglich.
Aufgabe 1 (Theorie: 10 Punkte):
ADT Baum
Auf den Folien der Vorlesung wurde der ADT Binärbaum mit den Operatoren is_empty, height, right,
left und value vorgestellt. Fügen Sie noch eine Funktion size hinzu, die die Anzahl der Elemente im
Baum berechnet.
Lösung
Signatur: size: BiBa<T> → Nat
Axiome:
size(create) = null
size(BiBa(left, e, right)) = succ(plus(size(left), size(right)))
Aufgabe 2 (Theorie: 15 Punkte):
Traversieren eines Binärer Baums
Durchlaufen Sie
den rechts
stehenden Baum
1. In-Order
2. Pre-Order
3. Post-Order
Lösung
1. Bei Inorder wird zuerst rekursiv der linke baum besucht, dann der Knoten selbst und anschließend der rechte baum.
D -> B -> E -> A -> F -> C -> G
2. Bei Preorder wird zuerst der Knoten selbst besucht und danach der linke und dann der rechte baum
A -> B -> D -> E -> C -> F -> G
3. Bei Postorder werden erst beide bäume durchlaufen (erst links dann rechts), bevor der Knoten selbst besucht wird.
D -> E -> B -> F -> G -> C -> A
Aufgabe 3 (Theorie: 5+15+5=25 Punkte):
Pre-Order, In-Order
1. Sie erhalten eine Liste von Zahlen, von der Ihnen gesagt wird, es handele sich um die
(eindeutigen) Knotenschlüssel eines Binärbaums in Preorder- Reihenfolge. Können Sie daraus
den ursprünglichen Baum eindeutig rekonstruieren?
2. Sie erhalten nun zwei Listen von Zahlen, einmal die Preorder- und einmal die InorderReihenfolge der Knoten desselben Binärbaums. Ist hier eine eindeutige Rekonstruktion möglich?
3. Funktioniert das Verfahren ohne Weiteres mit nicht binären Bäumen (wo also ein Knoten mehr
als 2 Unterbäume haben kann)?
Lösung
1. Nein, kann man nicht, da es zu einer Preorder-Sequenz mehrere Bäume geben kann. Beispiel: A B - C - D ist die Preordersequenz zu folgenden zwei - offenbar nicht gleichen - Bäumen:
A
/ \
B
A
\
D
B
/ \
/
C
C
D
2. Wenn Pre-order- und In-order-Durchlauf gegeben sind, kann man tatsächlich mit folgendem
Verfahren den Ursprungsbaum rekonstruieren:
1. Wähle das erste Pre-order-Element als Pivot-Element aus.
2. Teile die In-order-Liste in zwei Teile: links vom Pivot-Element und rechts vom
Pivot-Element.
3. Wähle das nächste Element aus der Pre-order-Sequenz als Pivot-Element.
Ist das Pivot-Element in der linken Liste, so ist es das linke Kind des vorigen
Pivot-Elements. Gehe zu Schritt 2 mit dem Rest der Pre-Order-Liste als neuer
Pre-Order-Liste, mit der linken Liste als neuer In-Order-Liste und mit dem aktuellen
Pivot-Element.
Ist das Pivot-Element in der rechten Liste, so ist es das rechte Kind des vorigen
Pivot-Elements. Gehe zu Schritt 2 mit dem Rest der Pre-Order-Liste als neuer
Pre-Order-Liste, mit der rechten Liste als neuer In-Order-Liste und mit dem aktuellen
Pivot-Element.
3. Nein, der Begriff "inorder" wie er im Skript definiert ist, macht nur Sinn für binäre Bäume, wo
ein "self"-Knoten nur max. 2 Unterbäume haben kann zwischen denen das "self"-Element steht.
Gibt es mehr als 2 Unterbäume, ist nicht mehr klar zwischen welchen Ünterbäumen das
"self"-Element stehen sollte (zumindest nicht ohne "inorder" umzudefinieren).
Aufgabe 4 (Theorie: 12+12+16 = 40 Punkte):
1. Zeichnen sie einen Baum (der kein Binärbaum sein soll, sondern bei dem jeder Knoten mehrere
Kinder haben kann) mit mindestens 15 Knoten. Bezeichen sie die Knoten in sog. Dewey-Notation
(also z.B. 1.6.3.4 fuer das 4.Kind des 3. Kindes des 6. Kindes des Wurzelknotens).
Nummerieren sie die Knoten in (a) preorder (in der Grafik farbig oder Zahl-in-Kreis) sowie (b)
postorder (in der Grafik mit einer anderen Farbe oder Zahl-in-Rechteck). Legen sie außerdem
eine Tabelle an mit folgenden Spalten:
1. Knoten-Nummer (Dewey)
2. Preorder-Nummer
3. Postorder-Nummer
4. Tiefe des Knotens (mit depth(root)=0)
5. Anzahl seiner Kinder
2. Sei x ein innerer Knoten ihres Baumes (z.B. Dewey-Nummer 1.3.2).
Beschreiben sie - ohne Beweis - anhand der in der Tabelle abgelegten Daten, wie sie die
folgenden Knotenmengen charakterisieren können (ohne Verwendung der Dewey-Notation):
den Vaterknoten (parent)
alle Vorfahren bis hin zur Wurzel (ancestors)
seine Kindknoten (children)
alle Nachfahren (d.h. Kinder, Kindeskinder etc: descendants)
seine Geschwisterknoten (siblings)
3. Beweisen sie:
post(x) = pre(x) - depth(x) + ||descendants(x)|| *
* - Hinweis: pre(x) bezeichnet in diesem Zusammenhang nicht den Operator auf dem ADT Baum,
der einen ADT Baum in einen ADT Liste umwandelt, sondern hier liefert pre(x) den preorder-Wert
des Knotens x als Zahl (also genau die Zahl, die sie zuvor an jeden Knoten ihres Baumes als
Zahl-im-Kreis geschrieben haben). post(x) analog.
Lösung
1. Beliebiges Beispiel machen ...
2.
1. Vater (parent): {x | pre(x) < pre(self) AND post(x) > post(self) AND depth(x) =
depth(self)-1}
2. Vorfahren (ancestors): {x | pre(x) < pre(self) AND post(x) > post(self) AND depth(x) <
depth(self)}
3. Kinder (children): {x | pre(x) < pre(self) AND post(x) > post(self) AND depth(x) =
depth(self)+1}
4. Nachfahren (descendants): {x | pre(x) < pre(self) AND post(x) > post(self) AND depth(x) >
depth(self)}
5. Geschwister: {x | parent(x) = parent(self) }
3. Beweis durch Induktion, Beginn beim root-Element.
Grundidee für den Induktionsschluss:
Bei einem preorder-Durchlauf wird erst der Vaterknoten von x besucht, dann alle linken
Geschwistern von x und deren Nachkommen, dann x selber. pre(x) ist also pre(parent(x)) +
#linke Geschwistern + Summe aller Nachkommen aller linken Geschwistern (siehe (2)).
Für postorder lässt sich eine ähnliche Gleichung aufstellen (siehe (3)).
Außerdem ist klar dass sich die Nachkommen von parent(x) zusammensetzen aus den linken
Geschwistern von x und deren Nachkommen, den rechten Geschwistern von x und ihren
Nachkommen, sowie x selber und seinen Nachkommen.
Mit diesen Informationen sowie der Induktionsbehauptung, dass die für x zu beweisende Aussage
bereits für parent(x) gilt, kann man das Gleichungssystem lösen.
Induktionsbeginn: Aussage "post(root) = pre(root) - depth(root) + ||descendants(root)||" gilt für
root:
Sei die Anzahl der Knoten im Baum insgesamt n. Dann gilt:
post(root) = n
pre(root) - depth(root) + ||descendants(root)||
1 - 0 + (n-1) = n. fertig.
parent(x) → x:
Zu zeigen: post(x) = pre(x) - depth(x) + ||descendants(x)||
Annahme: post(y) = pre(y) - depth(y) + ||descendants(y)|| für y = parent(x)
Es ist bekannt:
depth(x) = depth(y) + 1 (1)
pre(x) = pre(y) + ||L|| + ||desc(L)|| + 1 (2), wobei L die Menge aller linken Geschwister von x ist
post(y) = post(x) + ||R|| + ||desc(R)|| + 1 (3), wobei R die Menge aller rechten Geschwister von x
ist
Damit und mit der Induktionsannahme kann man nun folgern:
(3) ⇒
post(x) = post(y) - ||R|| - ||desc(R)|| - 1 (4)
Wenn man (2) von (4) abzieht, erhält man:
post(x) - pre(x) = post(y) - ||R|| - ||desc(R)|| - 1 - pre(y) - ||L|| - ||desc(L)|| - 1 =
post(x) - pre(x) = post(y) - pre(y) - (||R|| + ||desc(R)|| + ||L|| + ||desc(L)||) - 2 (5)
Außerdem gilt offenbar:
||desc(y)|| = ||L|| + ||desc(L)|| + 1 + ||desc(x)|| + ||R|| + ||desc(R)||, umgeformt:
||desc(y)|| - ||desc(x)|| - 1 = ||L|| + ||desc(L)|| + ||R|| + ||desc(R)|| (6)
Einsetzen in (5) liefert:
post(x) - pre(x) = post(y) - pre(y) - (||desc(y)|| - ||desc(x)|| - 1) - 2, umgeformt:
post(x) = post(y) - pre(y) + pre(x) + ||desc(x)|| - ||desc(y)|| - 1 (7).
Einsetzen der Induktionsannahme für post(y) auf der rechten Seite liefert:
post(x) = (pre(y) - depth(y) + ||desc(y)||) - pre(y) + pre(x) + ||desc(x)|| - ||desc(y)|| - 1 =
post(x) = - depth(y) + pre(x) + ||desc(x)|| - 1. (8)
Einsetzen von (1) liefert:
post(x) = - (depth(x) - 1) + pre(x) + ||desc(x)|| - 1 =
post(x) = + pre(x) - (depth(x) ||desc(x)||. Fertig.
Aufgabe 5 (Theorie: 10 Punkte):
Binäre Suchbäume
Gegeben sei folgender Suchbaum:
Fügen Sie die "4" in den Baum ein und löschen Sie anschließend die "3" aus dem Baum.
Lösung
Löschen der "3":
Einfügen der "4":
Die "3" ist ein innerer Knoten mit zwei Kindknoten. Folglich muss der
Knoten durch den am weitesten links stehenden Knoten des rechten
Unterbaums ersetzt werden, da dieser in der Sortierreihenfolge der nächste ist.
Herunterladen