Übungsblatt 6 - TUM - Technische Universität München

Werbung
Technische Universität München
Institut für Informatik
Lehrstuhl für Computer Graphik & Visualisierung
Praktikum: Grundlagen der Programmierung
Prof. R. Westermann, R. Fraedrich, R. Fülöp, H.G. Menz
WS 2009
Aufgabenblatt 6
2. Dezember 2009
Abgabe: In KW 50/51 (10. Dezember – 16. Dezember) vor der Übung.
Listen, Keller, Schlangen, Sortierung
Die Evaluation zu dem Praktikum finden Sie ab Donnerstag auf http://pgdp.in.tum.de.
6.1 (Ü) Wiederholung: Datentypen, Klassen
Formal bezeichnet ein Datentyp in der Informatik die Zusammenfassung von Objektmengen mit
den darauf definierten Operationen. (aus Wikipedia)
Erklären Sie die Unterschiede und Gemeinsamkeiten von primitiven Datentypen und Klassen:
(a) Kurz: Welche primitiven Datentypen haben Sie bereits kennengelernt bzw. verwendet? Und
welche Klassen?
(b) Wer legt fest, welche Datentypen existieren? Wo kann man das nachlesen?
(c) Welche Operationen sind erlaubt? Wer legt diese fest? Gibt es nur binäre Operationen?
(d) Erklären Sie die Begriffe Infix-, Präfix- und Postfix-Notation.
6.2 (Ü) Fragen zu Klassen
(a) Wie sieht eine einfach verkettete Liste aus? Wie eine doppelt verkettete?
(b) Erklären Sie die grundlegenden Konzepte hinter den Begriffen LIFO, FIFO, Stack (Keller),
Queue (Schlange). Erklären Sie, wie man die gebräuchlichsten Operationen dieser Klassen
implementieren würde (v.a. Einfügen und Entfernen von Elementen).
(c) Man kann eine Klasse “Liste” entweder mit Hilfe eines Arrays oder mit Hilfe einer verketteten
Liste implementieren. Diskutieren Sie Vor- und Nachteile dieser beiden Herangehensweisen.
(d) Was ist ein Baum? Was ist ein Binärbaum? Wie ordnet man Objekte zu einer Baumstruktur
an?
(e) Was ist ein Pfad? Was ist die Höhe eines Baumes? Was ist ein balancierter Baum?
(f) Baumtraversierung: Erklären Sie die Begriffe Breitensuche, Tiefensuche, Pre-Order-, In-Orderund Post-Order-Traversierung.
1
6.3 (Ü) Listen
Im Folgenden wird eine Möglichkeit vorgestellt eine einfach verkettete Liste zu implementieren.
Zunächst wird eine Klasse benötigt die ein einzelnes Element der Liste speichert, in diesem Fall
ein int. Weiterhin enthält die Klasse eine Referenz auf das nachfolgende Element. null bedeutet,
dass kein nachfolgendes Element existiert.
public class IntegerItem {
public int value ;
public IntegerItem next = null ;
IntegerItem ( int i ) {
value = i ;
}
}
Die eigentliche Liste wird in der Klasse
de.tum.ws2009.grprog.uebungsblatt06.list.IntegerSingleLinkedList
implementiert. Das erste Element der Liste wird in head gespeichert.
public class I n t e g e r S i n g l e L i n k e d L i s t {
p r i v a t e I n t e g e r I t e m head = n u l l ;
p u b l i c v o i d add ( i n t v ) {
I n t e g e r I t e m i t e m = new I n t e g e r I t e m ( v ) ;
i t e m . n e x t = head ;
head = i t e m ;
}
p u b l i c boolean d e l e t e ( i n t i ) {
int counter = 0;
I n t e g e r I t e m c u r r = head ;
IntegerItem last = null ;
w h i l e ( c u r r != n u l l ) {
i f ( c o u n t e r == i ) {
i f ( l a s t == n u l l )
head = head . n e x t ;
else
l a s t . next = curr . next ;
return true ;
}
++c o u n t e r ;
last = curr ;
curr = curr . next ;
}
2
return f a l s e ;
}
public String toString () {
String result = ” [ ” ;
f o r ( I n t e g e r I t e m c u r r = head ;
c u r r != n u l l ;
curr = curr . next ) {
r e s u l t += c u r r . v a l u e ;
i f ( c u r r . n e x t != n u l l )
r e s u l t += ” , ” ;
}
return r e s u l t + ” ] ” ;
}
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
I n t e g e r S i n g l e L i n k e d L i s t l i s t = new I n t e g e r S i n g l e L i n k e d L i s t ( ) ;
l i s t . add ( 1 ) ;
l i s t . add ( 2 ) ;
l i s t . add ( 8 ) ;
System . o u t . p r i n t l n ( l i s t ) ;
l i s t . delete (1);
System . o u t . p r i n t l n ( l i s t ) ;
}
}
Was ist die Ausgabe dieses Programmes? Wofür gibt es in der Methode boolean delete(int i)
eine Referenze last? Wann gibt boolean delete(int i) den boolschen Wert true zurück und
wann false.
Erstellen Sie nun eine Membermethode, die alle Vorkommen einer Zahl in der Liste löscht.
6.4 (Ü) Verkettete Listen
Realisieren Sie nun ein Adressbuch mit Hilfe einer einfach verketteten Liste.
Erstellen Sie hierzu die Klasse AddressbookItem die eine Instanz von Friend und einen Zeiger
next auf das nächste Element der Liste enthält.
In der Klasse SingleLinkedListAddressbook sollen nun folgende Methoden angeboten werden:
(a) public void add(Friend f) fügt einen Eintrag zu dem Adressbuch hinzu.
(b) public String toString() gibt die Elemente der Liste in einem String zurück.
(c) public void delete(int i) löscht den i-ten Eintrag aus dem Adressbuch.
(d) public void delete(String name) löscht den ersten Eintrag mit dem Nachnamen name
aus dem Adressbuch.
(e) public SingleLinkedListAddressbook append(SingleLinkedListAddressbook addressBook)
fügt ein anderes Addressbuch zu diesem hinzu und gibt eine neue Liste zurück, die alle Elmente der ursprünglichen und die der übergebenen Liste enthält.
3
Testen Sie Ihre Liste mit geeigneten Ein- und Ausgaben.
6.5 (Ü) Support
Für den IT-Support soll ein Ticketsystem erstellt werden. Implementieren Sie hierfür eine Klasse
Support, die neue Anfragen mit public void add(Ticket ticket) anlegt. Mitarbeiter können
mit der Methode public Ticket get() die älteste Anfrage abrufen.
Erstellen Sie hierfür eine Klasse Ticket. Ein Ticket enthält einen Namen, eine Email Adresse und
eine Anfrage. Alle drei sollen über eine public String toString() Methode ausgegeben werden
können.
Welche Datenstruktur bietet sich am ehesten für diese Problemstellung an. Verwenden Sie die
besprochene einfach verkette Liste als Basis für Ihre Lösung.
6.6 (H) Binärbaum
(14 Punkte)
In dieser Aufgabe werden wir ein Adressbuch auf der Grundlage eines Binärbaums implementieren.
Erstellen sie eine Klasse, die einen Knoten im Binärbaum repräsentiert. Sie erinnern sich: Jeder
Knoten eines Baumes ist selbst wieder die Wurzel eines Baumes.
Ein Binärbaum und ein (beispielhaftes) UML-Diagramm der zu erstellenden Knotenklasse
Als “Nutzlast” soll jeder Knoten eine Instanz der Klasse Friend (siehe Übungsblatt 5) enthalten.
Der Binärbaum soll geordnet sein, d.h. die Knoten des Baumes sind stets nach einem bestimmten
Schema sortiert. In unserem Fall sind die Nutzdaten vom Typ Friend. Bei Kontakten ist eine
Sortierung wie im Telefonbuch (zuerst Nachnahme, dann Vorname) naheliegend. Die Friend-Klasse
bietet eine Methode compareTo, mit deren Hilfe man die Reihenfolge zweier Adressbucheinträge
bestimmen kann. Nutzen Sie diese Methode, um beim Modifizieren des Baumes sicherzustellen,
dass immer und für jeden Knoten (und nicht nur für die Wurzel) gilt:
Alle Kontakte im linken Unterbaum kommen vor dem Kontakt im aktuellen Knoten und alle Kontakte im rechten Unterbaum kommen nach dem Kontakt im aktuellen Knoten.
Baumstruktur
Implementieren Sie:
4
(a) Die Knotenklasse de.tum.ws2009.grprog.uebungsblatt06.BinaryTree selbst. Ein Knoten enthält Nutzdaten und seine beiden Kinder.
Ihre Knotenklasse soll außerdem (mindestens) folgende Methoden enthalten:
(b) public boolean isLeaf(): Gibt an, ob ein Knoten ein Blatt ist oder nicht.
(c) public int getNumberOfNodes(): Liefert die Zahl der Knoten eines Baumes (einschließlich des Wurzelknotens).
(d) public int getHeight(): gibt die Höhe des Baumes zurück, dessen Wurzel dieser Knoten
ist. Die Höhe eines Baumes ist definiert als Länge des längsten Pfades von der Würzel zu
einem Blatt. Beispiel: Ein Baum, der nur aus der Wurzel besteht, hat also Höhe 0; ein Baum
bestehend aus zwei Knoten hat Höhe 1.
Traversierung
Schreiben Sie drei Methoden, die jeweils den Inhalt des Baumes als String zurückgeben. Der
String soll aus mehreren Zeilen bestehen, eine Zeile pro Kontakt. Benutzen sie Friend.toString(),
um einen Kontakt in einen String umzuwandeln. Einen Zeilenumbruch fügen sie mit der Zeichenkette \n an.
(e) public String toStringPreOrder(): Gibt die Kontakte eines Baumes in folgender Reihenfolge zurück: Zuerst den Kontakt in der Wurzel, dann die Kontakte des linken Teilbaumes
und dann die Kontakte des rechten Teilbaumes.
(f) public String toStringInOrder(): Gibt die Kontakte eines Baumes in folgender Reihenfolge zurück: Zuerst die Kontakte des linken Teilbaumes, dann den Kontakt in der Wurzel
und dann die Kontakte des rechten Teilbaumes.
(g) public String toStringPostOrder(): Gibt die Kontakte eines Baumes in folgender Reihenfolge zurück: Zuerst die Kontakte des linken Teilbaumes, dann die Kontakte des rechten
Teilbaumes und dann den Kontakt der Wurzel.
Welche der drei Methoden gibt die Kontakte in der “richtigen” Reihenfolge (Telefonbuchsortierung) zurück? Vermerken Sie dies im JavaDoc der entsprechenden Funktion.
Einfügen und Suchen
(h) public boolean insert(Friend data): Mit dieser Methode wird bei einem bestehenden
Baum ein neues Datenelement eingefügt. Das Datenelement soll an die “richtige” Stelle im
Baum eingefügt werden, so dass die oben beschriebene Sortierung der Knoten erhalten bleibt.
Die Methode liefert true zurück, wenn das Element erfolgreich eingefügt werden konnte und
false wenn bereits ein entsprechendes Element im Baum vorhanden war. Sie müssen sich
nicht um die Balancierung des Baumes kümmern - durchlaufen Sie in ihrer Implementierung
den Baum einfach bis zu einer Stelle, an der das neue Element als Blatt hinzugefügt werden
kann.
(i) public SingleLinkedListAddressbook find(String searchRequest): Liefert eine Liste zurück, welche alle Kontakte enthält, die zu einer gegebenen Suchanfrage passen. Zu der
Anfrage “liese” würden z.B. die Kontakte Lieselotte Franzmaier, Anneliese Schmidthuber und
Hans Fliesenleger passen. Die Ergebnisliste soll sortiert sein.
5
Herunterladen