TECHNISCHE UNIVERSITÄT MÜNCHEN FAKULTÄT FÜR INFORMATIK Lehrstuhl für Sprachen und Beschreibungsstrukturen Einführung in die Informatik I Prof. Dr. Helmut Seidl, M. Schwarz, A. Herz, Dr. M. Petter WS 11/12 Übungsblatt 9 15.12.11 Abgabe: 08.01.12 (vor 24 Uhr) Aufgabe 9.1 (P) Einache Linked Lists Einfach verkettete Integer-Listen bestehen aus einer Kette von Elementen. Jedes Element besteht aus einer Zahl (info) und der Referenz (next) auf den Rest der Liste. Die leere Liste wird durch null repräsentiert. a) Erstellen Sie eine Klasse IntList. Implementieren Sie einen passenden Konstruktor, der die Attribute info und next initialisiert. b) Implementieren Sie eine Methode append(int info), die eine neue Liste zurückgibt, die eine Kopie der aktuellen Liste ist, an deren Ende ein neues Element mit Zahl info, angefügt wurde. c) Implementieren Sie eine Methode public String toString(), die alle Elemente der Liste als String zurückgibt. d) Implementieren Sie eine Methode sum(), die die Summe aller Listenelemente zurückgibt. e) Implementieren Sie eine Methode reverse(), die eine neue Liste zurückgibt, welche die Zahlen der aktuellen Liste in umgekehrter Reihenfolge enthält. Lösungsvorschlag 9.1 public c l a s s I n t L i s t { private int info ; private I n t L i s t next ; // t h e i n t d a t a o f t h i s l i s t e l e m e n t // t h e r e s t o f t h e l i s t /∗ ∗ ∗ S e t s up a new i n s t a n c e o f I n t L i s t c o r r e s p o n d i n g t o t h e g i v e n i n f o and ∗ next . ∗ @param i n f o t h e i n t d a t a o f t h i s l i s t e l e m e n t ∗ @param n e x t t h e r e s t o f t h e l i s t ∗/ public I n t L i s t ( int i n f o , I n t L i s t next ) { this . i n f o = i n f o ; t h i s . next = next ; } /∗ ∗ ∗ A new l i s t where t h e g i v e n i n f o has been appended . ∗ @param i n f o t h e i n t d a t a o f t h e new l i s t e l e m e n t ∗ @return a new i n s t a n c e o f I n t L i s t ∗/ public I n t L i s t append ( int i n f o ) { i f ( next == null ) return new I n t L i s t ( t h i s . i n f o , new I n t L i s t ( i n f o , null ) ) ; 2 else return new I n t L i s t ( t h i s . i n f o , next . append ( i n f o ) ) ; } /∗ ∗ ∗ Computes t h e sum o f a l l e l e m e n t s o f t h i s l i s t . ∗ @return t h e sum o f a l l e l e m e n t s ∗/ public int sum ( ) { i f ( next == null ) return i n f o ; else return i n f o + next . sum ( ) ; } /∗ ∗ ∗ Auxiliary function for the reversal of t h i s l i s t . ∗ @param acc t h e l i s t e l e m e n t s a c c u m u l a t e d so f a r ∗ @return a new i n s t a n c e o f I n t L i s t ∗/ private I n t L i s t r e v e r s e A u x ( I n t L i s t a c c ) { i f ( next == null ) return new I n t L i s t ( i n f o , a c c ) ; else return next . r e v e r s e A u x (new I n t L i s t ( i n f o , a c c ) ) ; } /∗ ∗ ∗ A new l i s t w i t h t h e e l e m e n t s o f t h i s l i s t i n r e v e r s e o r d e r . ∗ @return a new i n s t a n c e o f I n t L i s t ∗/ public I n t L i s t r e v e r s e ( ) { return r e v e r s e A u x ( null ) ; } /∗ ∗ ∗ String representation of t h i s l i s t . ∗/ @Override public S t r i n g t o S t r i n g ( ) { i f ( next == null ) return ” ” + i n f o ; else return i n f o + ” , ” + next ; } public s t a t i c void main ( S t r i n g [ ] a r g s ) { I n t L i s t l s t = new I n t L i s t ( 1 , null ) ; fo r ( int i = 2 ; i < 1 0 ; i ++) l s t = l s t . append ( i ) ; System . out . p r i n t l n ( l s t ) ; System . out . p r i n t l n ( l s t . r e v e r s e ( ) ) ; System . out . p r i n t l n ( l s t . sum ( ) ) ; } } 3 Aufgabe 9.2 (P) Binärer Suchbaum 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. Beispiel: In der obigen Zeichnung finden Sie einen BSB für die Zahlen 1, 3, 6, 7, 8, 10, 13, 14. Entwerfen und realisieren Sie die Datenstrukturen und Methoden für binäre Suchbäume: a) Erstellen Sie eine Klasse BSB, mit der Sie binäre Suchbäume darstellen können. Ergänzen Sie die Klasse BSB um folgende Methoden: b) boolean contains(int n), die zurückgibt, ob die Zahl n im BSB enthalten ist. c) void insert(int n), die – unter Erhalt der obigen Eigenschaften – einen neuen Knoten mit dem Wert n in den BSB einfügt, falls dieser Wert im BSB nicht schon vorhanden ist. Beispiel: Die folgende Zeichnung illustriert einen Aufruf von insert(4): insert(4) −→ d) String toString(), die eine String-Darstellung der Baumstruktur zurückgibt. Beispiel: toString() liefert für den obigen BSB den String: [ [ 1 ] 3 [ 6 [ 7 ] ] ] 8 [ 10 [ [ 13 ] 14 ] ] Lösungsvorschlag 9.2 public c l a s s BSB { private BSB l e f t ; private BSB r i g h t ; private int v a l u e ; public BSB( int v ) { value = v ; } /∗ public // } public // boolean contains ( in t n) { . . . Aufgabe a ) void i n s e r t ( in t n) { . . . Aufgabe b ) 4 } } ∗/ /∗ ∗ ∗ checks i f element n i s in t r e e ∗/ public boolean c o n t a i n s ( int n ) { i f ( n == v a l u e ) { return true ; } e l s e i f ( n > v a l u e && r i g h t != null ) { return r i g h t . c o n t a i n s ( n ) ; } e l s e i f ( n < v a l u e && l e f t != null ) { return l e f t . c o n t a i n s ( n ) ; } return f a l s e ; } /∗ ∗ ∗ I n s e r t s a new node w i t h v a l u e n i n t o t h e BSB ∗/ public void i n s e r t ( int n ) { i f ( ! contains (n) ){ i f (n > value ) { i f ( r i g h t == null ) { r i g h t = new BSB( n ) ; } else { right . insert (n) ; } } else { i f ( l e f t == null ) { l e f t = new BSB( n ) ; } else { l e f t . insert (n) ; } } } } public s t a t i c void main ( S t r i n g [ ] a r g s ) { BSB b = new BSB( 5 ) ; b . insert (7) ; b . insert (2) ; b . insert (8) ; System . out . p r i n t l n ( b . c o n t a i n s ( 8 ) ) ; System . out . p r i n t l n ( b ) ; } @Override public S t r i n g t o S t r i n g ( ) { S t r i n g l e f t S t r i n g = ”” ; S t r i n g r i g h t S t r i n g = ”” ; i f ( g e t L e f t ( ) != null ) { leftString = getLeft () . toString () ; 5 } i f ( g e t R i g h t ( ) != null ) { r i g h t S t r i n g = getRight () . toString () ; } return ” [ ” + l e f t S t r i n g + ” ” + g e t V a l u e ( ) + ” ” + r i g h t S t r i n g + ”] ”; } }