Übung 24.11.2014

Werbung
Technische Universität München
Institut für Informatik
Lehrstuhl für Bioinformatik
Einführung in die Programmierung für Bioinformatiker
Prof. B. Rost, L. Richter
WS 2014/15
Aufgabenblatt 6
24.11.2014
Java, ADT
6.1 (Ü) Listen und Polymorphe
In der folgenden Aufgabe entwickeln Sie objekt-orientiert eine Kombination aus dem abstrakten
Datentyp Liste und polymorphen Nutzdaten. Genauer ausgedrückt handelt es sich um eine einfach
verkettete Liste. Dieser ADT wird häufig auch als Queue bezeichnet. Die Liste wird durch eine
Klasse, die die Funktionalität bereitstellt, gebildet und eine Klasse, die die Listenelemente enthält.
Dementsprechend muss nur ein ”Verwaltungsobjekt” aber mehrere Objekte für die Listenelemente
erzeugt werden. Um Erfahrung mit Polymorphie zu sammeln, handelt es sich bei den gespeicherten
Nutzelementen um Objekte mit einer Vererbungsbeziehung. Der eigentliche Zusammenbau erfolgt
dann innerhalb der main-Methode einer eigenen Treiberklasse.
Die Liste unterstützt folgende Funktionen:
•
•
•
•
addElement(...) fügt ein Element am Ende hinzu
removeElement() entfernt das Element am Anfang und gibt es zurück
getHead() gibt das Element am Anfang zurück
toString(): Gibt eine numerierte Textdarstellung der Listenelemente aus
Um das in Java zu implementieren, brauchen wir folgende Klassen:
(a) Student: Wird mit einem Namen und einer Matrikelnummer erzeugt. toString() gibt den
Namen und die Matrikelnummer in einer Zeile aus.
(b) Fachschaft: Unterklasse von Student. Zusätzlich gibt es ein Amt, das bei der Erzeugung
angegeben werden kann, oder erst später gesetzt wird. toString() gibt nach Name und Matrikelnummer meine Aufgabe in der Fachschaft: ünd die Aufgabe aus.
(c) Listenelement: Enthält eine Referenz auf ein Student-Objekt und eine Referenz auf das
nächste Listenelement. Gibt es keine nächstes Element ist der Wert null.
(d) Liste: Implementiert die oben angegebenen Funktionen und enthält eine Referenz auf das
erste Listenelement.
(e) Driver : Dieser Klasse erzeugt in ihrer main()-Methode verschiedene Studenten und Fachschafter und speichtert sie in der Liste bzw. entfernt sie auch wieder. Die Liste wird zu
verschiedenen Zeitpunkten am Bildschirm ausgegeben.
1
6.2 (Ü) Unveränderbarer Binärbaum
Ein Binärbaum ist ein Baum, in dem alle Knoten einen Wert und 2 Teilbäume
haben. Bei einem Binären Suchbaum (BSB) gilt für jeden Knoten des Baumes,
dass sein Wert:
• grösser ist als die Werte aller Knoten in seinem linken Teilbaum;
• kleiner ist als die Werte aller Knoten in seinem rechten Teilbaum;
• maximal einmal im ganzen BSB vorkommt.
Man bezeichnet dies auch als Bauminvariante.
Beispiel: In der obigen Zeichnung finden Sie einen BSB f:̈ur die Zahlen 1, 3, 6, 7, 8, 10, 13, 14.
(a) Entwerfen und realisieren Sie eine Datenstruktur BinaryTree für binäre Suchbäume für
ganze Zahlen (int). Auf die Objektattribute soll von außen nicht zugegriffen werden können.
Außerdem sollen die Objektattribute nur initial bei der Deklaration oder durch den später
zu implementierenden Konstruktor gesetzt werden und anschließend nicht mehr verändert
werden können (final).
Es soll eine unveränderliche ( immutable“) Datenstruktur implementiert werden!
”
(b) Implementieren Sie einen Konstruktor, der eine ganze Zahlübergeben bekommt und damit
einen Binärbaum initialisiert, der nur diese Zahl enthält.
(c) Implementieren Sie einen privaten Konstruktor, der eine ganze Zahl sowie eine Referenz auf
einen linken und einen rechten Teilbaum übergeben bekommt. Da dieser Konstruktor nur von
der Klasse selbst verwendet werden kann, brauchen Sie an dieser Stelle nicht zu prüfen, ob
die Bauminvariante möglicherweise verletzt wurde.
Hinweis: Verwenden Sie diesen Konstruktor für die folgenden Methoden.
Es bietet sich an, die folgenden Methoden rekursiv zu formulieren und zu programmieren:
(d) Implementieren Sie eine Methode BinaryTree insert(int newElem), die eine Kopie dieses
Baumes zurückgibt, die außerdem das neue Element beinhaltet. Achten Sie dabei auf die
Einhaltung der Bauminvariante. Beispiel: Die folgende Zeichnung illustriert einen Aufruf von
insert(4):
insert(4)
−→
(e) Implementieren Sie eine Methode boolean contains(int elem), die true zurückgibt, falls
das übergebene Element im Baum vorkommt und false, falls nicht.
(f) Implementieren Sie eine Methode String toString(), die eine Zeichenkettenrepräsentation
der Baumstruktur zurückgibt. Beispiel: toString() liefert für den obigen linken Baum:
(((null,1,null),3,(null,6,(null,7, null))),8,(null,10,((null,13,null),14,null)))
(g) Implementieren Sie eine Methode int size(), die die Anzahl der Elemente des Baums
zurückgibt.
2
(h) Implementieren Sie eine Methode int depth(), die die Tiefe des Baums zurückgibt, sprich
die Anzahl der Kanten des längsten Pfades von der Wurzel bis zu einem Blatt (Blätter sind
kinderlose Knoten). Ein einelementiger Baum hat also die Tiefe 0.
(i) Optional: Implementieren Sie eine Methode String toStringDescending(), die die Elemente des Baums in absteigender Reihenfolge durch Kommata getrennt als Zeichenkette
zurückgibt.
(j) Optional: Implementieren Sie eine Methode boolean isBinarySearchTree(), die true
zurückgibt, falls die Bauminvariante für diesen Baum gilt und false, falls nicht.
6.3 (Ü) Interfaces
In dieser Aufgabe sollen die Klassen aus Blatt 5 (Geometrische Flächen und Prismen) erweitert
werden.
(a) Einerseits sollen Klassen vom Typ Prisma und Grundflaeche untereinander und miteinander
vergleichbar gemacht werden in dem beide Klassen das Interface java.lang.Comparable
implementieren.
• Prismen werden nach Größe des Volumens (ist das Volumen gleich, dann zählt die
größere Oberfläche) verglichen;
• Grundflaechen werden nach Größe der Fläche verglichen;
• Prismen werden über ihre Grundflaeche mit anderen Grundflaechen verglichen;
(b) Testen Sie die Implementierung, indem Sie eine ArrayList von Grundflaeche mittels java.util.
Collections.sort() sortieren.
(c) Als zweiten Schritt sollen die Methoden istQuadrat und zuQuadrat in ein Interface Quadrierbar
ausgelagert werden, welches nur von solchen Grundflaechen implementiert werden soll, die
auch ein Quadrat darstellen können.
(d) Fügen Sie eine weitere Grundflaeche Dreieck zur Modellierung von rechtwinkligen Dreiecken zu den bereits bestehenden Grundflaechen hinzu. Ein (rechtwinkliges) Dreieck wird
durch die Länge der Hypotenuse und Ankathete parametrisiert.
(e) Zuletzt erstellen wir ein weiteres Interface Polygon mit nur einer Methode
int getEckenAnzahl(), welche die Zahl der in einer Grundfläche enthaltenen Ecken zurückgibt.
(f) Implementieren Sie Polygon für alle Grundflaechen, die eine endliche Anzahl von Ecken
besitzen.
(g) Testen Sie Quadrierbar und Polygon, indem Sie über eine sortierte ArrayList vom Typ
java.lang.Comparable, welches Prisma und Grundflaechen enthält, iterieren und mittels
instanceof die Verfügbarkeit beider Interfaces abfragen und, falls vorhanden, die aus diesen
Interfaces ermittelbaren Informationen ausgeben.
3
Herunterladen