Einführung in die Programmierung (EPR)

Ähnliche Dokumente
Einführung in die Programmierung (EPR) (Übung, Wintersemester 2014/2015)

Natürliche Bäume. (Algorithmen und Datenstrukturen I) Prof. Dr. Oliver Braun. Letzte Änderung: :16. Natürliche Bäume 1/16

Vorlesung Datenstrukturen

Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung)

Anwendungsbeispiel MinHeap

Aufgaben, Hilfestellungen und Musterlösungen zum Modul 5 Druckversion

Dokumentation zum AVL-Baum (C++)

Grundlagen der Informatik

Trees. November 14, Algorithms & Datastructures 2 Exercises WT 2017

Einführung in die Programmierung (EPR)

Übungen zu Programmierung I - Blatt 8

Trees. November 13, Algorithms & Datastructures 2 Exercises WT 2017

Teil 1: Suchen. Ausgeglichene Bäume B-Bäume Digitale Suchbäume. M.O.Franz, Oktober 2007 Algorithmen und Datenstrukturen - Binärbäume 1-1

Algorithmen und Datenstrukturen. Bäume. M. Herpers, Y. Jung, P. Klingebiel

Übung Datenstrukturen. Bäume

Technische Universität München. Vorlesungsgrobstruktur: wo stehen wir, wie geht s weiter

Binäre Suchbäume. Mengen, Funktionalität, Binäre Suchbäume, Heaps, Treaps

Algorithmen & Datenstrukturen 2 Praktikum 1

Informatik. Pointer (Dynamisch) Vorlesung. 17. Dezember 2018 SoSe 2018 FB Ing - SB Umwelttechnik und Dienstleistung - Informatik Thomas Hoch 1

Tutoraufgabe 1 (Implementierung eines ADTs):

Informatik II, SS 2014

Prüfung Algorithmen und Datenstrukturen I

B6.1 Introduction. Algorithmen und Datenstrukturen. Algorithmen und Datenstrukturen. B6.1 Introduction. B6.3 Analyse. B6.4 Ordnungsbasierte Methoden

Institut für Programmierung und Reaktive Systeme 7. Mai Programmieren II. 11. Übungsblatt

Informatik Abitur Bayern 2017 / II - Lösung

Datenstrukturen. einfach verkettete Liste

Lösungshinweise/-vorschläge zum Übungsblatt 13: Software-Entwicklung 1 (WS 2017/18)

18. Natürliche Suchbäume

1 Der Baum. Informatik I: Einführung in die Programmierung 11. Bäume. Bäume in der Informatik. Bäume in der Informatik - Definition.

Übungen zur Vorlesung EINI (WS 2010) Blatt 11

Binärbäume: Beispiel

Vorlesung Informatik 2 Algorithmen und Datenstrukturen

Dynamische Datenstrukturen in C++ 150

Informatik II, SS 2016

In diesem Kapitel behandeln wir erste Algorithmen mit dynamischen Strukturen, wie Bäume und Graphen. 1. Bäume Grundlagen...

Datenstrukturen Teil 2. Bäume. Definition. Definition. Definition. Bäume sind verallgemeinerte Listen. Sie sind weiter spezielle Graphen

Algorithmen und Datenstrukturen

Einführung in die Programmierung II. 9. Dynamische Datenstrukturen: Binärbäume

Algorithmen und Datenstrukturen

1 Der Baum. Informatik I: Einführung in die Programmierung 11. Bäume. Bäume in der Informatik. Bäume in der Informatik - Definition.

Algorithmen und Datenstrukturen. Algorithmen und Datenstrukturen. B4.1 Definitionen und Eigenschaften. B4.2 Traversierung. B4.

Übungen zur Vorlesung EidP (WS 2015/16) Blatt 6

Klausur: Grundlagen der Informatik I, am 27. März 2009 Gruppe: F Dirk Seeber, h_da, Fb Informatik. Nachname: Vorname: Matr.-Nr.

Informatik II, SS 2014

Algorithmen und Datenstrukturen 1

Wiederholung. Bäume sind zyklenfrei. Rekursive Definition: Baum = Wurzelknoten + disjunkte Menge von Kindbäumen.

Informatik II, SS 2016

Prüfung Algorithmen und Datenstrukturen I

Mengen. Binäre Suchbäume. Mengen: Anwendungen (II) Mengen: Lösung mit Listen 12/3/12. Mengen, Funktionalität, Binäre Suchbäume, Heaps, Treaps

Institut für Programmierung und Reaktive Systeme 10. Mai Programmieren II. 11. Übungsblatt

Informatik II, SS 2014

Vorlesung Datenstrukturen

Software Entwicklung 1

Algorithmen und Datenstrukturen Suchbaum

Bäume, Anwendung und Begriffe

Übung 4: Die generische Klasse AvlBaum in Java 1

Abgabe: (vor der Vorlesung) Aufgabe 7.1 (P) Binomial Heap

19. Vererbung und Polymorphie

Algorithmen und Datenstrukturen (ESE) Entwurf, Analyse und Umsetzung von Algorithmen (IEMS) WS 2013 / Vorlesung 10, Donnerstag 9.

Algorithmen und Datenstrukturen

1. Motivation / Grundlagen 2. Sortierverfahren 3. Elementare Datenstrukturen / Anwendungen 4. Bäume / Graphen 5. Hashing 6. Algorithmische Geometrie

Algorithmen und Datenstrukturen

Einfache binäre Suchbäume können entarten, so dass sich die Tiefen ihrer Blattknoten stark unterscheiden

Datenstrukturen & Algorithmen

Klausur: Informatik, am 13. August 2015 Dirk Seeber, h_da, Fb Informatik. Nachname: Vorname: Matr.-Nr.: Punkte:

Tutoraufgabe 1 (Implementierung eines ADTs):

Algorithmen und Datenstrukturen I Bruder-Bäume

Praxis der Programmierung

Algorithmen und Datenstrukturen

Wintersemester 2004/ Dezember 2004

7. Vererbung und Polymorphie

Informatik II Vorlesung am D-BAUG der ETH Zürich

7. Dynamische Datenstrukturen Bäume. Informatik II für Verkehrsingenieure

Logische Datenstrukturen

Suchbäume. Suchbäume. Einfügen in Binären Suchbäumen. Suchen in Binären Suchbäumen. Prinzip Suchbaum. Algorithmen und Datenstrukturen

Algorithmen und Datenstrukturen 2. Dynamische Datenstrukturen

Geordnete Binärbäume

Einführung in die Informatik 2

Datenstrukturen und Algorithmen (SS 2013)

Informatik II Prüfungsvorbereitungskurs

Lösungsvorschläge zur Hauptklausur Datenstrukturen

9. Natürliche Suchbäume

Algorithmen und Datenstrukturen (ESE) Entwurf, Analyse und Umsetzung von Algorithmen (IEMS) WS 2014 / Vorlesung 10, Donnerstag 8.

Informatik II Bäume zum effizienten Information Retrieval

Algorithmen und Datenstrukturen. Kapitel 4: Suchverfahren. Skript zur Vorlesung. Algorithmen und Datenstrukturen

Einführung in die Objektorientierte Programmierung Vorlesung 18: Lineare Datenstrukturen. Sebastian Küpper

14. Rot-Schwarz-Bäume

Institut für Programmierung und Reaktive Systeme 28. Mai Programmieren II. 12. Übungsblatt

Entwickeln Sie ein C/C++-Programm für die Verwaltung einer Artikeldatei gemäß folgender Vorgaben!

Einführung in die Informatik 2

elementare Datenstrukturen

Klausur: Grundlagen der Informatik I, am 27. März 2009 Gruppe: E Dirk Seeber, h_da, Fb Informatik. Nachname: Vorname: Matr.-Nr.

18. Vererbung und Polymorphie

Tutoraufgabe 1 (Listen):

Übung Informatik I - Programmierung - Blatt 8

Transkript:

Goethe-Center for Scientific Computing (G-CSC) Goethe-Universität Frankfurt am Main Einführung in die Programmierung (EPR) (Übung, Wintersemester 2014/2015) Dr. S. Reiter, M. Rupp, Dr. A. Vogel, Dr. K. Xylouris, Prof. Dr. G. Wittum Aufgabenblatt 7 (Abgabe: Fr., 19.12., 9:29h online) Eine häufig verwendete und sehr nützliche Datenstruktur ist der Binärbaum. Ein Beispiel für einen Binärbaum ist wie folgt: gerichtete Verbindung (edge) Wurzel (root) Innerer Knoten (inner) Blatt (leaf) Die Elemente eines Binärbaums werden als Knoten bezeichnet. Die Knoten sind durch gerichtete Kanten verbunden. Dabei gilt in einem Binärbaum, dass von jedem Knoten nur maximal zwei Verbindungen ausgehen dürfen. Einer der Knoten ist dadurch ausgezeichnet, dass er keine eingehende Verbindung besitzt und wird als Wurzel (engl. root) bezeichnet. Alle anderen Knoten haben genau eine eingehende Verbindung. Geht eine gerichtete Verbindung von einem Knoten A zu Knoten B, so wird A als Elternteil und B als Kind bezeichnet. Hat ein Knoten keine Kinder, so wird er als Blatt (engl. leaf) des Baumes bezeichnet. Nimmt man zu einem Knoten seine Kinder und rekursiv deren Kinder, so erhält man wiederum einen Binärbaum, der als Teilbaum (engl. subtree) bezeichnet wird. Mit jedem der Knoten kann zusätzlich ein Wert (sogenannter Schlüssel) assoziiert werden. Auf diesem Aufgabenblatt soll dieser Schlüssel vom Datentyp int sein. Anschaulich ergeben sich dann z.b. folgende Bäume: 5 17 8 8 22 5 oder 11 oder 3 20 67 Um einen solchen Binärbaum zu realisieren, bietet es sich an eine Struktur für jeden Knoten einzuführen (vgl. verkettete Liste):

/// Node structure to represent a node in a binary tree struct Node { int value; ///< value associated with node Node* left; ///< left subtree ( == 0, if no subtree present) Node* right; ///< right subtree ( == 0, if no subtree present) ; Eine Instanz der Struktur Node repräsentiert dabei einen Eintrag in einem binären Baum. Die Membervariable value speichert den Wert, der mit dem Eintrag verbunden ist. Die Membervariablen left und right speichern einen Zeiger auf den linken bzw. rechten Teilbaum. Dies kann man sich anschaulich so vorstellen, dass die Knoten im Binärbaum folgendermaßen aussehen: 6 4 8 Ist eine der Verbindungen nach links oder rechts nicht vorhanden, so wird der Nullzeiger gesetzt. Ein Blatt ist somit eine Node, bei der beide Zeiger den Wert 0 besitzen. Ein Binärbaum heißt binärer Suchbaum, falls er zusätzlich die folgende Eigenschaft erfüllt: Die Schlüssel im linken Teilbaum eines Knotens sind kleiner oder gleich dem Schlüssel im Knoten selbst und die Schlüssel im rechten Teilbaum sind alle echt größer. Die oben dargestellten Bäume erfüllen beispielsweise diese Eigenschaft. Aufgabe 1 (4 + 6 + 4 + 4 + 6 + 6 + 1 Punkte) Schreiben Sie die folgenden Funktionen: a) Node* CreateNode(int value): Diese Methode soll eine Instanz der Struktur Node über den Befehl new erstellen, diese wie folgt initialisieren und als Zeiger zurückgeben: Die Membervariable value der neuen Struktur soll auf den übergebenen Wert value gesetzt werden, die beiden Membervariablen left und right sollen auf 0 gesetzt werden. b) void InsertNode(Node* root, Node* node): Fügt den übergebenen Knoten node in den übergebenen Baum root ein. Dabei wird angenommen, dass sowohl root als auch node bei der Übergabe die Eigenschaft eines binären Suchbaums erfüllen. Nach dem Einfügen von node soll diese Eigenschaft für root weiterhin gelten.

c) void InsertValue(Node* root, int value): Erstellt einen neuen Knoten mit dem Wert value und fügt diesen in den übergebenen Baum root ein. Nutzen Sie hierbei die Funktionen CreateNode und InsertNode. Achten Sie darauf, dass nach Terminierung auch hier root wieder die Eigenschaft eines binären Suchbaums erfüllt. d) Node* CreateTree(int* values, int size): Erstellt einen Baum und fügt die übergebenen Werte ein. values ist dabei ein Zeiger auf ein Feld von int-werten, size gibt die Zahl an Werten in diesem Feld an. Die Methode gibt einen Zeiger auf die Wurzel des erstellten Baums zurück. Nutzen Sie hierbei die Methoden CreateNode und InsertValue. Achten Sie darauf, dass der zurückgegebene Baum die Eigenschaft eines binären Suchbaums erfüllt. e) void PrintTreeSorted(Node* root): Gibt die Einträge des Baums root sortiert auf dem Bildschirm aus. Die Reihenfolge soll dabei in aufsteigender Ordung ausgegeben werden, d.h. niedrige Schlüssel zuerst. Man betrachte dazu das Beispiel aus Aufgabenteil (g). f) void DeleteTree(Node* root): Löscht den Baum mit Wurzel root, indem mittels des delete Befehls der Speicher aller zugehörigen Knoten frei gegeben wird. Neben der Wurzel root sind auch alle Kind-Knoten, also alle Knoten in den Teilbäumen root->left und root->right, zu löschen. g) Testen Sie Ihre Implementierung mit dem folgenden Programm: #include <iostream> using namespace std; //... Ihr Quelltext... int values[] = {7, 1, 3, 8, 2, 9, 5, 4, 6, 0; Node* tree = CreateTree(values, 10); PrintTreeSorted(tree); cout << endl; // Erwartete Ausgabe: 0 1 2 3 4 5 6 7 8 9 Hinweis: Für die Implementierung der Methoden PrintTreeSorted und DeleteTree ist ein rekursiver Ansatz empfehlenswert. Auch die Methode InsertNode eignet sich gut für eine rekursive Implementierung. Aufgabe 2 (6 + 6 + 6 + 1 Punkte) Erweitern Sie den Quelltext aus Aufgabe 1 um die folgenden Funktionen:

a) int NumTreeNodes(Node* root): Berechnet die Anzahl an Knoten des Baums mit Wurzel root (inklusive root) und gibt diese zurück. b) int TreeDepth(Node* root): Berechnet die Tiefe des Baums mit Wurzel root und gibt diese zurück. Die Tiefe eines Binären Baums mit Wurzel Node* t wird dabei formal wie folgt definiert: 0, falls t == 0 depth(t) = 1 + max(depth(t->left), depth(t->right)), sonst. c) void PrintTree(Node* root): Im Gegensatz zu PrintTreeSorted soll diese Funktion die Struktur des Baums auf dem Bildschirm ausgeben. Dazu wird jeweils der Wert eines Knotens ausgegeben. Hat der Knoten einen linken oder rechten Teilbaum, so wird anschließend das Symbol ( ausgegeben. In der Klammer wird nun zunächst der linke Teilbaum mittels PrintTree ausgegeben, gefolgt vom Symbol,, anschließend der rechte Teilbaum, wieder mittels PrintTree, gefolgt vom abschließenden Symbol ). Für das Beispiel aus Aufgabe 1(g) sollte die Funktion dementsprechend folgendes ausgeben: 7(1(0,3(2,5(4,6))),8(,9)) d) Testen Sie Ihre Implementierung mit folgendem Programm: #include <iostream> using namespace std; //... Ihr Quelltext... int values[] = {8, 12, 5, 24, 2, 6, 98, 67, 1, 4, 312, 380, 410, 612, 780; Node* tree = CreateTree(values, 15); cout << endl << "NumTreeNodes: " << NumTreeNodes(tree) << endl; cout << "TreeDepth: " << TreeDepth(tree) << endl << endl; Aufgabe 3 (Bonuspunkte: 4 + 5 + 1) Erweitern Sie den Quelltext aus Aufgaben 1 und 2 um die folgenden Funktionen: a) Node* FindNode(Node* root, int value): Gibt den Knoten in dem durch root gegebenen Baum zurück, der den Wert value enthält. Ist kein Knoten mit diesem Wert im Baum, so wird der Nullzeiger 0 zurückgegeben.

Nutzen Sie bei der Implementierung die spezielle Eigenschaft binärer Suchbäume, um bei der Suche jeweils möglichst wenige Knoten zu besuchen. b) Node* RemoveNode(Node* root, Node* node): Entfernt den Knoten node aus dem durch root gegebenen Baum. Die von node ausgehenden Teilbäume (node->left und node->right) sollen dabei nicht gelöscht werden und müssen dementsprechend wieder in den Baum root eingefügt werden. Die Funktion gibt einen Zeiger auf die Wurzel des so entstandenen Baums zurück. Es ist dabei darauf zu achten, dass der entstandene Baum wieder die Eigenschaft eines binären Suchbaums erfüllt und dass der Speicher des entfernten Knotens node frei gegeben wird. Nutzen Sie auch hier bei der Implementierung die spezielle Eigenschaft binärer Suchbäume, um beim Löschen jeweils möglichst wenige Knoten zu besuchen. c) Testen Sie Ihre Implementierung mit folgendem Programm: int values[] = {8, 12, 5, 2, 6, 67, 24, 98, 1, 4; Node* tree = CreateTree(values, 10); // remove an entry from the tree int delval = 67; cout << endl << "Removing " << delval << " from tree:" << endl; Node* delnode = FindNode(tree, delval); if(delnode) tree = RemoveNode(tree, delnode); cout << endl; Information zum Zeitrahmen: Zur Bearbeitung dieses Aufgabenblatts haben Sie zwei Wochen Zeit. Es empfiehlt sich frühzeitig mit der Bearbeitung zu beginnen und auftauchende Fragen gegebenenfalls in der Übungsgruppe zu stellen. Information zur Abgabe: Bitte schicken Sie Ihre Lösung als *.cpp Datei an Ihren Übungsgruppenleiter per Mail. Wichtig ist, dass Sie Ihre Lösung freitags vor 9:30h abgeschickt haben. Bitte schicken Sie nur den Quellcode, nicht jedoch ihr gesamtes Eclipse- Projekt oder ausführbare Dateien.