public Binaerbaum(BinaerbaumInterface<Type> left,
Type value, BinaerbaumInterface<Type> right)
public BinaerbaumInterface<Type> left();
public BinaerbaumInterface<Type> right();
Das heißt ja, das mischen von Typen in einem Binärbaum ist unmöglich, obwohl die Axiome meiner Meinung nach darüber ja keine Aussage treffen.
BinaerbaumInterface<String> eins = new Binaerbaum<String>(null, "eins", null);
BinaerbaumInterface<Integer> zwei = new Binaerbaum<Integer>(eins, 2, null);
Ergibt den Fehler:
The constructor Binaerbaum<Integer>(BinaerbaumInterface<String>, int, null) is undefined
Soll der Baum also wirklich an einen Typ gebunden sein?
Das sag ich, mit der Begründung, dass es das am einfachsten zu verwirklichende aufgabenstellungskonforme Verhalten ist (ein Dreizeiler: if (v!=null) println(…v.toString()…); if (left!=null) left.traverse(n+1); if (right!=null) right.traverse(n+1); ) und jedes speziellere Verhalten in der Aufgabenstellung weiter hätte spezifiziert werden müssen.
Anscheinend wollte man in der Aufgabe unbedingt ein neues feature von Java1.5 verwenden, welches man übrigens in C++ bereits seit 16 Jahren unter dem Begriff „template“ kennt.
Eine Möglichkeit, beliebige Typen in einem Baum/Liste zu speichern ist, die Tatsache auszunutzen, dass sämtliche Objekte von der Klasse „Object“ erben; also Type=Object. Für einen späteren Zugriff (welcher über toString() hinausgeht) muss man sie dann aber richtig casten, was einen verwaltungstechnischen Mehraufwand bedeutet. In der Realität ist es wohl sehr unüblich, Objekte völlig verschiedenen Typs in einem Baum speichern zu wollen.
Wenn man z.B. Hunde, Katzen und Mäuse in einem Baum speichern will, dann würde man wohl wählen: Type=Tier. Bei Bäumen und Listen geht es ja letztendlich darum, Dinge zu speichern, welche gemeinsame Eigenschaften haben (um sie z.B. zu sortieren), welche üblicherweise durch eine gemeinsame Oberklasse oder ein gemeinsames Interface gegeben sind.
a) “null” ist kein Binärbaum, von daher ist in der Aufgabe
BinaerbaumInterface eins = new Binaerbaum(null, “eins”, null);
nicht unbedingt gewollt.
b) traverse(2536536) geht davon aus, das der Teilbaum auf der Tiefe 2536536 beginnt.
c) ja, das mit der private traverse(int); und public traverse(); Methode wäre vielleicht eine besserer Modelierung gewesen, aber dann hätte ich bestimmt wieder tonnen von nachfragen bekommen, was denn der Unterschied ziwschen diesen beiden Methoden ist. Deswegen diesmal nur eine
Es spricht übrigens nichts dagegen, dass ihr eine [m]public traverse()[/m] implementiert, auch wenn sie nicht explizit gefordert ist. Schöner ist es damit auf jeden Fall, man kann dann halt einfach [m]irgendeinBaum.traverse()[/m] aufrufen.
Meinst du reinzufällig vielleicht eher (oder auch), dass new Binaerbaum(foo, null, bar); nicht gewollt ist?
Ohne null-Verweise (auf nichtexistente Kinder) wäre doch jeder Baum unendlich groß.
Selbst die Alternative new Binaerbaum(new Binaerbaum(), „eins“, new Binaerbaum()) heißt ja nix anderes als zwei Kinder deren Attribute alle null sind, also wieder das was „nicht unbedingt gewollt“ ist.
Ich wollte halt keine Binärbäume, die nur “einen” Nachfogler haben, so wie das halt in der Signatur geschreiben ist.
Es gibt den Leeren baum (create) und dann Bäume die aus zwei Bäumen aufgebaut sind.
“null” ist kein Baum, da man an ihm keine Methoden Aufrufen kann.Wie die Interne Struktur des leeren Baumes aussieht ist egal, da jeder ja nur auf seine nach Signatur erlaubten Methoden zugreifen kann. left(create), right(create), value(create) sind nicht spezifiziert von daher werden sie nicht aufgerufen, aber empty und traverse muss richtig funktionieren.
Das bedeutet wohl, dass man eine boolean-Variable z.B. „empty“ anlegen muss, die beim Constructor Binaerbaum(void) auf true gesetzt wird, ansonsten auf false, welche dann von der Funktion empty() benutzt wird.
Bei so einem Beispiel muss es also klappen:
BinaerbaumInterface<Object> leererBaum = new Binaerbaum<Object>();
BinaerbaumInterface<Object> eins = new Binaerbaum<Object>(leererBaum, 1, leererBaum);
BinaerbaumInterface<Object> neun = new Binaerbaum<Object>(leererBaum, 9, leererBaum);
BinaerbaumInterface<Object> zwei = new Binaerbaum<Object>(leererBaum, "zwei", leererBaum);
BinaerbaumInterface<Object> vier = new Binaerbaum<Object>(zwei, 4.0, leererBaum);
BinaerbaumInterface<Object> sieben = new Binaerbaum<Object>(eins, "sieben", neun);
BinaerbaumInterface<Object> fuenf = new Binaerbaum<Object>(leererBaum, 5, vier);
BinaerbaumInterface<Object> drei = new Binaerbaum<Object>(sieben, 3, fuenf);
drei.traverse(0);