/*******************************************************************/ /* Prof. Dr. Carsten Vogt */ /* FH Koeln, Fak. 07 / Nachrichtentechnik */ /* http://www.nt.fh-koeln.de/vogt */ /* */ /* Das Programm definiert eine Klasse fuer Knoten von Binaerbaeume */ /* sowie Methoden zur Ein- und Ausgabe von Binaerbaeumen. */ /* */ /* ANMERKUNG: Aus unbekanntem Grund lässt sich das Programm aus */ /* dem Java-Editor heraus nicht ausführen - beim readLine()-Aufruf */ /* kommt es zu einer Fehlermeldung. Ruft man das Programm von der */ /* DOS-Oberflaeche auf, laeuft es einwandfrei. */ /* */ /*******************************************************************/ import java.io.*; import java.util.*; import java.awt.*; import javax.swing.*; /**************************************************************** Die Klasse 'Binaerknoten' definiert Knoten in Binaerbaeumen. *****************************************************************/ class Binaerknoten { // Attribute Object wert; // Eintrag des Knotens: kann jedes beliebige Objekt sein String wertDarstellung; // Stringdarstellung des Eintrags, // wird bei einer Bildschirmanzeige des Knotens ausgegeben Binaerknoten linkerSohn, // Verweis auf den linken Sohn rechterSohn; // Verweis auf den rechten Sohn // Konstruktor: besetzt die vier Attribute mit den uebergebenen Werten vor Binaerknoten(Object wert, String wertDarstellung, Binaerknoten linkerSohn, Binaerknoten rechterSohn) { this.wert = wert; this.wertDarstellung = wertDarstellung; this.linkerSohn = linkerSohn; this.rechterSohn = rechterSohn; } } /*********************************************************************** Die Klasse 'BinaerbaumTest' definiert Methoden zur Ein- und Ausgabe von Baeumen und enthaelt ein Hauptprogramm, in dem diese Methoden aufgerufen werden. ************************************************************************/ public class BinaerbaumTest { /* Methode zum Einlesen eines Binaerbaums. Der Baum wird Ebene fuer Ebene eingelesen, d.h. zunaechst die Wurzel, dann deren beiden Soehne, dann die Soehne dieser Knoten usw. Rueckgabewert ist ein Verweis auf das Wurzelobjekt. */ static Binaerknoten baumEinlesen() throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); Binaerknoten wurzel; // Wurzel des neuen Baums String eingabetext; // Text zum Einsetzen in einen neuen Knoten // Einlesen des Wurzelknotens System.out.print("Bitte Wurzeleintrag (oder RETURN, wenn der Baum leer ist) eingeben: "); eingabetext = in.readLine(); if (eingabetext.length()==0) { // Rueckkehr, wenn Wurzelknoten leer System.out.println("Baum ist leer"); return null; } // Erzeugung des neuen Wurzelknoten wurzel = new Binaerknoten(eingabetext,eingabetext,null,null); // Erzeugung einer Liste: Enthaelt die Knoten, deren Soehne noch eingegeben werden muessen. ArrayList nochOffeneSoehne = new ArrayList(); nochOffeneSoehne.add(wurzel); // Schleife, die so lange laeuft, wie noch Soehne eingegeben werden muessen while (!nochOffeneSoehne.isEmpty()) { // Auslesen des ersten Knotens mit noch offenen Sohneintraegen aus der Liste Binaerknoten aktKnoten = (Binaerknoten) nochOffeneSoehne.remove(0); // Eingabe des Eintrags des linken Sohns fuer diesen Knoten System.out.println(); System.out.print("Bitte linken Sohn von " + aktKnoten.wertDarstellung + " oder RETURN (wenn nicht vorhanden) eingeben: "); eingabetext = in.readLine(); if (eingabetext.length()!=0) { // Verweis des Knotens auf seinen neuen linken Sohn setzen aktKnoten.linkerSohn = new Binaerknoten(eingabetext,eingabetext,null,null); // Einfuegen des neuen linken Sohns in die Liste nochOffeneSoehne.add(aktKnoten.linkerSohn); } // Analog: Eingabe des rechten Sohns System.out.println(); System.out.print("Bitte rechten Sohn von " + aktKnoten.wertDarstellung + " oder RETURN (wenn nicht vorhanden) eingeben: "); eingabetext = in.readLine(); if (eingabetext.length()!=0) { aktKnoten.rechterSohn = new Binaerknoten(eingabetext,eingabetext,null,null); nochOffeneSoehne.add(aktKnoten.rechterSohn); } } return wurzel; } /* Methode zur Ausgabe der Eintraege eines Binaerbaums in Preorder */ static void ausgabePreorder(Binaerknoten wurzel) { if (wurzel!=null) { // Ausgabe der Wurzel System.out.print(wurzel.wertDarstellung+" "); // Ausgabe des linken Unterbaums in Preorder ausgabePreorder(wurzel.linkerSohn); // Ausgabe des rechten Unterbaums in Preorder ausgabePreorder(wurzel.rechterSohn); } } /* Methode zur Ausgabe der Eintraege eines Binaerbaums in Inorder */ static void ausgabeInorder(Binaerknoten wurzel) { if (wurzel!=null) { // Ausgabe des linken Unterbaums in Inorder ausgabeInorder(wurzel.linkerSohn); // Ausgabe der Wurzel System.out.print(wurzel.wertDarstellung+" "); // Ausgabe des rechten Unterbaums in Inorder ausgabeInorder(wurzel.rechterSohn); } } /* Methode zur Ausgabe der Eintraege eines Binaerbaums in Postorder */ static void ausgabePostorder(Binaerknoten wurzel) { if (wurzel!=null) { // Ausgabe des linken Unterbaums in Postorder ausgabePostorder(wurzel.linkerSohn); // Ausgabe des rechten Unterbaums in Postorder ausgabePostorder(wurzel.rechterSohn); // Ausgabe der Wurzel System.out.print(wurzel.wertDarstellung+" "); } } /* Methode zur Ausgabe der Baumstruktur: Der Baum wird auf einer zeichenorientierten Oberflaeche ausgegeben. Er wird dabei um 90 Grad gegen den Uhrzeigersinn gedreht, und die Tiefe der Knoten wird durch Einrueckungen angedeutet. */ static void ausgabeStruktur(Binaerknoten wurzel, int einrueck) { // Parameter einrueck gibt an, um wie weit die Darstellung // des Wurzelknotens nach rechts eingerueckt werden soll if (wurzel!=null) { // Ausgabe des rechten Unterbaums mit einer um 4 groesseren Einrueckung ausgabeStruktur(wurzel.rechterSohn,einrueck+4); // Ausgabe des Wurzelknoten, eingerueckt um 'einrueck' Positionen for (int i=0;i