Christoph Garbe: Algorithmen und Datenstrukturen, SS 09 Abgabe: bis 16.04.2009 Übungblatt 2 Aufgabe 1: Bäume und binäre Suchbäume 12 Punkte Sie haben in der Vorlesung allgemeine (n-äre) Bäume bereits kennen gelernt. Ein Spezialfall eines solchen Baumes ist ein binärer Baum, bei dem jeder Knoten maximal zwei Nachfahren haben kann. In C könnte man einen Knoten in einem binären Baum so darstellen: key struct node { node* left; // linker Kind-Knoten node* right; // rechter Kind-Knoten int key; // gespeicherter Wert/Schlüssel }; left right a) Zum Aufwärmen: Wie müsste man obige Datenstruktur anpassen, um einen Baum mit maximal 5 Kind-Knoten darzustellen? Wie wird in obiger Datenstruktur ein Blatt (also ein Knoten ohne Kinder) dargestellt? (2 Punkte) b) Wie lässt sich ein beliebiger (n-ärer) Baum als binärer Baum darstellen? Wie muss im Zweifel die obige Datenstruktur angepasst werden? Zeichnen Sie den binären Baum, der sich aus folgendem allgemeinen Baum ergibt! (5 Punkte) c) Es gibt eine Möglichkeit binäre Bäume in einem Feld (Array) darzustellen. Wie kann man das machen? Stellen Sie den Baum bei Aufgabe 1b) als Feld dar! (5Punkte) Aufgabe 2: Binärer Suchbaum 36 Punkte Ein binärer Suchbaum ist nun ein spezieller binärer Baum, bei dem folgende „Suchbaumeigenschaft“ in jedem Knoten erfüllt ist: Sei x ein beliebiger Knoten in einem binären Suchbaum. Für einen beliebigen Knoten yl aus dem linken Kind-Baum von x gilt, dass key[yl] ≤ key[x]. Für einen beliebigen Knoten yr aus dem rechten Kind-Baum von x gilt, dass key[yr] > key[x]. a) Wie kann man einen neuen Schlüssel in einen binären Suchbaum auf möglichst einfache Weise einfügen und wie löschen? Notieren Sie die Verfahren in C++ (nutzen Sie obige Knoten-Definition) oder in Pseudo-Code! Welche möglichen Fehlerbedingungen müssen behandelt werden? Zur Ausgabe Ihres Suchbaumes wurde bereits eine print()-Funktion implementiert. Diese können Sie zunächst als Black-Box betrachten, die den Baum in Level-Order ausgibt. (7+7 Punkte) Christoph Garbe: Algorithmen und Datenstrukturen, SS 09 Abgabe: bis 16.04.2009 Übungblatt 2 b) Zeichnen Sie den Baum, der entsteht, wenn man folgende Zahlen in der angegebenen Reichenfolge eingibt: 1,5,2,10,4,8,9,20,19,22. Was fällt an dem Baum auf? Wie groß müsste das Array sein, wenn der Baum wie in Aufgabe 1c) dargestellt werden soll? (3+2 Punkte) c) Geben Sie ein Verfahren an, mit dem man in einem binären Suchbaum den größten bzw. den kleinsten Schlüssel effizient finden kann. Geben Sie an, wie viele Knoten Ihre zwei Verfahren im Suchbaum aus Aufgabe b) überprüfen muss. Wie viele sind es im Folgend dargestellten Baum? (5 Punkte) Daten als Liste: 10, 5, 3, 15, 6, 14, 16, 28, 7, 17 d) Wie kann man überprüfen, ob ein bestimmter Schlüssel im Suchbaum enthalten ist? Geben Sie wieder die Anzahl der besuchten Knoten für die Bäume aus Aufgabe b) und c) an, wenn 19 bzw. 17 gesucht werden soll. (5+2 Punkte) e) Die Zahlen im Suchbaum aus 2c) lassen sich auch als Array darstellen (Beispiel siehe dort). Wie viele Vergleiche sind im Mittel nötig, um festzustellen, ob ein bestimmtes Element in einer solchen Liste der Länge N enthalten ist. Wie viele Vergleiche benötigt man im Mittel, um in einem binären Suchbaum auf Enthalten-Sein eines bestimmten Elements zu prüfen? (Tipp: Überlegen Sie sich, wie tief ein Suchbaum im Mittel ist. Lassen Sie dabei Extremfälle außen vor!) (2+3 Punkte) Aufgabe 3: Syntaxbaum 28 Punkte Syntaxbäume werden benutzt, um mathematische Ausdrücke im Computer darzustellen. Im folgenden sollen Sie Syntaxbäume betrachten, die die Operationen Addition (+) und Multiplikation (*) auf ganzen Zahlen 0..9 darstellen können. Die Regel Punkt-vor-Strich soll beachtet werden! Der folgende C-Code kann benutzt werden, um einen Knoten darzustellen. struct node { node* left; node* right; char type; int value; }; // // // // linker Kind-Knoten rechter Kind-Knoten Operation: ’+’ (Add.) , ’*’ (Mul.), ’ ’ (Zahl) gespeicherte Zahl a) Wie sieht folgender mathematischer Ausdruck (gegeben in Infix-Notation) in Post- und PräfixNotation aus? (1 Punkte) Christoph Garbe: Algorithmen und Datenstrukturen, SS 09 Abgabe: bis 16.04.2009 Übungblatt 2 3*(5+8*9)+2 b) Wie kann man aus einer Präfix Textrepräsentation eines Ausdrucks einen Baum aufbauen? Geben Sie den Syntaxbaum an, der sich aus der folgenden Eingabe ergibt: (5 Punkte) +3*5+43 *+*458+*+8921 c) Nach welchem Traversier-Verfahren ergibt sich der dargestellte Ausdruck in Infix-, Präfix- und nach welchem in Postfix-Notation? Bei welchen Verfahren ist die Ausgabe von Klammern nötig? (3 Punkte) d) Implementieren Sie die rekursive Traversierung eines Syntaxbaumes in C++ nach den drei Verfahren aus Aufgabe c). Nutzen Sie dazu das beigefügte Code-Gerüst. Nutzen Sie keine zusätzlichen Datenstrukturen (Stapel, Feld, …). (9 Punkte) e) Implementieren Sie ein Verfahren, das aus einer Zeichenkette (string) in Postfix-Notation einen Syntaxbaum aufbaut. Sie können entweder C++ oder Pseudocode abgeben. Nutzen Sie im ersten Fall das Code-Gerüst zur Aufgabe. Sie können dazu die Datenstruktur Stack benutzen, die in der C++-StandardBibliothek bereits implementiert ist (siehe http://www.cplusplus.com/reference/stl/stack/). Die Benutzug ist im Code-Template zu dieser Aufgabe kurz erklärt. (10 Punkte) Hinweise: Wenn Sie Bäume Graphen zeichnen wollen, können Sie natürlich Papier verwenden, oder ein beliebiges Graphik-Programm, es gibt aber auch spezialisierte Tools für solche Zwecke. Die Graphen auf diesem Übungszettel wurden z.B. mit GraphViz erstellt, dass Sie unter http://www.graphviz.org/ im Internet finden. In der C++-Standardbibliothek sind viele grundlegende Datenstrukturen bereits implementiert. Eine ausführliche Dokumentation mit viele Beispielen finden Sie unter http://www.cplusplus.com/. Die Codebausteine, auf welche Sie aufbauen sollten, finden Sie unter http://ipm.uni-hd.de/teaching/Algorithmen/Uebung/CodeBlatt2.zip