Informatik mit Java Bäume: Einfügen und Suchen Gierhardt Im Unterricht wurden die folgenden Klassen entwickelt: 1 2 3 public c l a s s Knoten { int i n h a l t ; Knoten l i n k s , r e c h t s ; 4 public Knoten ( i n t wert ) { t h i s . i n h a l t = wert ; this . l i n k s = null ; this . r e c h t s = null ; } 5 6 7 8 9 10 1 2 } public c l a s s BinaerBaum { Knoten w u r z e l ; 3 4 5 6 public BinaerBaum ( ) { wurzel = null ; } 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public void r e k Fu e g e E i n ( Knoten a s t , i n t wert ) { i f ( wert < a s t . i n h a l t ) { // l i n k s e i n f u e g e n i f ( a s t . l i n k s == n u l l ) a s t . l i n k s = new Knoten ( wert ) ; e l s e r e k Fu e g e E i n ( a s t . l i n k s , wert ) ; } e l s e { // r e c h t s e i n f u e g e n i f ( a s t . r e c h t s == n u l l ) a s t . r e c h t s = new Knoten ( wert ) ; e l s e r e k Fu e g e E i n ( a s t . r e c h t s , wert ) ; } } // rekFuegeEin 21 22 23 24 25 26 public void f u e g e E i n ( i n t wert ) { i f ( w u r z e l == n u l l ) w u r z e l = new Knoten ( wert ) ; e l s e r e k Fu e g e E i n ( w u r z e l , wert ) ; } // FuegeEin 27 28 29 30 31 32 33 34 public void rekLaufeDurch ( Knoten a s t ) { i f ( a s t != n u l l ) { rekLaufeDurch ( a s t . l i n k s ) ; Out . p r i n t ( a s t . i n h a l t ) ; Out . p r i n t l n ( ) ; rekLaufeDurch ( a s t . r e c h t s ) ; } } // rekLaufeDurch 35 36 37 38 39 40 41 42 43 public void l a u f e D u r c h ( ) { i f ( w u r z e l != n u l l ) { rekLaufeDurch ( w u r z e l . l i n k s ) ; Out . p r i n t ( w u r z e l . i n h a l t ) ; Out . p r i n t l n ( ) ; rekLaufeDurch ( w u r z e l . r e c h t s ) ; } } // l a u f e D u r c h } // c l a s s BinaerBaum 1 Ein dazugehöriges Hauptprogramm könnte so aussehen: 1 2 public c l a s s B i n a e r B a u m B e i s p i e l { BinaerBaum baum ; 3 4 5 6 public B i n a e r B a u m B e i s p i e l ( ) { baum = new BinaerBaum ( ) ; } 7 8 9 10 11 public void a c t i o n ( ) { int zahl = 0 ; Out . p r i n t ( " B i t t e ␣ Za hl e n ␣ e i n g e b e n . ␣Ende␣ mit ␣ −1. " ) ; Out . p r i n t l n ( ) ; 12 while ( z a h l != −1) { Out . p r i n t ( " B i t t e ␣ Zahl ␣ e i n g e b e n : ␣ " ) ; z a h l = In . r e a d I n t ( ) ; i f ( z a h l != −1) baum . f u e g e E i n ( z a h l ) ; } // w h i l e baum . l a u f e D u r c h ( ) ; 13 14 15 16 17 18 19 20 21 } } // c l a s s BinaerBaumBeispiel Aufgaben: 1. In einer Klasse können zwei Methoden den gleichen Namen haben, wenn sie sich durch die Parameterliste unterscheiden. Dies bezeichnet man als Überladen. Die Auswahl der tatsächlich aufzurufenden Methode erfolgt zur Laufzeit anhand des Typs der aktuellen Parameter. Der Ergebnistyp muss allerdings immer gleich bleiben. Das dem Überladen übergeordnete Konzept der Objektorientierung ist die Polymorphie, was so viel wie „Vielgestaltigkeit“ heißt. Ein weiteres Beispiel für Polymorphie ist die Verwendung des +-Operators, der bei Zahlen die Addition und bei Strings die Konkatenation bewirkt. Wende das Überladen bei den Methoden der Klasse BinaerBaum an. 2. Die Methode laufeDurch() ist zu umständlich formuliert. Vereinfache sie. 3. Der Baum soll nach bestimmten Inhalten durchsucht werden. Formuliere dazu eine Funktion gefunden(int zahl) und teste die Methode. Tipp: Überladen und natürlich Rekursion machen die Lösung einfach. 4. Die Klasse BinaerBaum wird um drei Konstanten ergänzt und die Methode laufeDurch erhält einen weiteren Parameter. Formuliere damit die Methoden um, damit der Baum auf verschiedene Arten durchlaufen werden kann. Teste die verschiedenen Arten aus. 1 2 c l a s s BinaerBaum // −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− { Knoten w u r z e l = n u l l ; 3 4 5 6 7 8 9 10 f i n a l i n t INORDER = 1; f i n a l i n t PREORDER = 2 ; f i n a l i n t POSTORDER = 3 ; ... void l a u f e D u r c h ( i n t o r d e r ) ... } // c l a s s BinaerBaum 2