Java Probleme mit Binärbaum...

Status
Für weitere Antworten geschlossen.

Sico1337

Newbie
Registriert
Jan. 2015
Beiträge
5
Moin!

Ich habe ein Problem bzgl. der sog. Inorder-Abfrage eines sehr überschaubaren Binärbaumes:

Code:
public class Aufgabe13 {
	
	Node tree = new Node(5,
			new Node(3,
				new Node(1, null, null),
				new Node(4, null, null)
			),
			new Node(8,
				new Node(6, null, null),
				new Node(9, null, null)
			)
		);
	
	
}
	
	class Node {
		
		public Node left;
		public Node right;
		public int value;
	
		
		public Node(int v, Node l, Node r) {
			value = v;
			left = l;
			right = r;
			}
		
		public static String inorder(Node n) {
			
			if (n == null) return "";
			return inorder(n.left) +
			n+
			inorder(n.right);
		}
	
		
		
	
		public static void main(String[] args){
			
			System.out.println("" + inorder(Node n));
		}
}

Meine erste Frage: Wieso bekomme ich diese Fehlermeldung?:

Exception in thread "main" java.lang.Error: Unresolved compilation problems:
Node cannot be resolved to a variable
Syntax error on token "n", delete this token

at Node.main(Aufgabe13.java:43)

Zweite Frage: Ich muss den Binärbaum mit 37, 17 und 42 erweitern, kann meine Lösungsansätze aber leider nicht kontrollieren, da ich ja nichtmal diese einfache Ausgabe zum Laufen bringe...

Hätte da diese zwei Ideen:

Code:
Node tree = new Node(5,
	new Node(3,
		new Node(1, null, null),
		new Node(4, null, null)
	),
	new Node(8,
		new Node(6, null, null),
		new Node(9, null, null)
	),
	new Node(37,
		new Node(17, null, null),
		new Node(42, null, null)
	),
		);


Oder:

Code:
Node tree = new Node(5,
	new Node(3,
		new Node(1, null, null),
		new Node(4, null, null)
	),
	new Node(8,
		new Node(6, null, null),
		new Node(9,
	),
	new Node(37,
		new Node(17, null, null),
		new Node(42, null, null)
	),

...oder sind die beide völlig falsch?

Vielen Dank schonmal an Alle, die hier mirgrübeln! :)
 
Mach in Zeile 43 das Node weg. Typangaben sind beim Funktionsaufruf fehl am Platz. Außerdem musst du das n vorher noch mit irgendwas initialisieren.

Deine beiden Lösungsvorschläge sind auch falsch. Beim ersten hat dein Node 5 plötzlich 3 Kind-Knoten, das zweite ist schon allein aus syntaktischen Gründen falsch, hat aber auch sonst wohl das gleiche Problem wie der erste Vorschlag.
Anhand deiner Lösungsvorschläge lässt sich nicht sagen, ob du nur Probleme mit dem Java-Syntax hast oder das Konzept des Binärbaums nicht richtig verstanden hast. Vielleicht beschreibst du am besten Mal in Worten oder Pseudocode was du genau machen willst, dann kann vielleicht besser erkennen wo es hapert.

Deine Strukturierung ist übrigens auch etwas seltsam. Normalerweise gilt für Java: Eine Klasse -> EIne Datei mit gleichem Namen.
 
Zuletzt bearbeitet:
Das hatte ich auch schon probiert und folgendes kam dann zurück:

Exception in thread "main" java.lang.Error: Unresolved compilation problem:
n cannot be resolved to a variable

at Node.main(Aufgabe13.java:43)
 
"n" muss natürlich vorher als variable deklariert werden :)
 
Ich würde mal die Main Methode nicht in die Class Node schreiben sondern alleine...
 
n ist nirgends deklariert. Was du vermutlich machen sollst ist die Variable tree static machen (also ein static vor Node tree = new Node(5, ... in Zeile 3). Die main Methode sollte in die Klasse Aufgabe13 und zu

Code:
public static void main(String[] args){
			
			System.out.println("" + Node.inorder(tree));
		}
geändert werden
 
Ich hoffe ich habe das richtig verstanden, demnach sähe das Ganze dann wie folgt aus:

Code:
public class Aufgabe13 {
	

	public static void main(String[] args){
		
		System.out.println("" + Node.inorder(tree));
	}
	
	static Node tree = new Node(5,
			new Node(3,
				new Node(1, null, null),
				new Node(4, null, null)
			),
			new Node(8,
				new Node(6, null, null),
				new Node(9, null, null)
			)
		);
	
	
}
	
	class Node {
		
		public Node left;
		public Node right;
		public int value;
	
		
		public Node(int v, Node l, Node r) {
			value = v;
			left = l;
			right = r;
			}
		
		public static String inorder(Node n) {
			
			if (n == null) return "";
			return inorder(n.left) +
			n+
			inorder(n.right);
		}
	
		
		
	
}

...kommt leider das hier bei heraus:

Fehler: Hauptmethode in Klasse Node nicht gefunden. Definieren Sie die Hauptmethode als:
public static void main(String[] args)
 
Sico1337 schrieb:
Fehler: Hauptmethode in Klasse Node nicht gefunden. Definieren Sie die Hauptmethode als:
public static void main(String[] args)

Womit programmierst Du denn? Das ist keine Standard-Compiler-Fehlermeldung.

Schaut so aus, als ob die main() in der Klasse Node soll. Die Klasse Aufgabe 13 vermutlich weg (deren Code dann wohl auch in Node).
 
Mit Eclipse

Eclipse Standard/SDK

Version: Kepler Service Release 1
Build id: 20130919-0819

(c) Copyright Eclipse contributors and others 2000, 2013. All rights reserved.
Visit http://eclipse.org/eclipse

This product includes software developed by the
Apache Software Foundation http://apache.org/
Ergänzung ()

Okay, es ist jetzt schonmal etwas anderes als eine Fehlermeldung gekommen! :D

Code:
	class Node {
		
		public Node left;
		public Node right;
		public int value;
	
		
		public Node(int v, Node l, Node r) {
			value = v;
			left = l;
			right = r;
			}
		
		public static String inorder(Node n) {
			
			if (n == null) return "";
			return inorder(n.left) +
			n+
			inorder(n.right);
		}
	
		public static void main(String[] args){
			
			System.out.println("" + Node.inorder(tree));
		}
		
		static Node tree = new Node(5,
				new Node(3,
					new Node(1, null, null),
					new Node(4, null, null)
				),
				new Node(8,
					new Node(6, null, null),
					new Node(9, null, null)
				)
			);
}

Und die Ausgabe:

Node@7e3b014cNode@53d26552Node@19fa157cNode@71988d36Node@565f0e7dNode@7ab05cd7Node@509f662e

Gehört das so? :D
 
Die Fehlermeldung ist schon ok. Sie kommt nur selten vor, weil sie, wenn man den Konventionen folgt eher selten auftritt.

Ich habe es gerade mal getestet. Wenn man zwei Klassen in eine Datei schreibt (hier Aufgabe13 und Node), dann erstellt der Java-Compiler zwei .class Dateien. Ich spekuliere mal drauf los und sage, dass du die Datei Node.java genannt hast und Eclipse dann ohne weitere Konfiguration einfach davon ausgeht, dass es die Node.class ausführen soll, was natürlich misslingt, weil die Node Klasse keine main Funktion hat. Am besten wäre es also, wenn du dich an die Konvention halten würdest und jeder Klasse eine eigene Datei gönnst. Dann kommt Eclipse auch nicht durcheinander. Ansonsten musst das Eclipse-Projekt so umkonfigurieren, dass es die Aufgabe13.class ausführt und nicht die Node.class.
 
Sico1337 schrieb:
Und die Ausgabe:

Node@7e3b014cNode@53d26552Node@19fa157cNode@71988d36Node@565f0e7dNode@7ab05cd7Node@509f662e

Gehört das so? :D

Das ist das Standard-Verhalten, ja. Wenn es nicht gefällt, muss man die Methode toString() überschreiben.
 
Vielen Dank schonmal an Alle! :)

Bei mir sieht das folgendermaßen aus:

Aufgabe13.JPG

Und das mit toString()... Dazu müsste ich doch einfach

Code:
public static String inorder.toString(Node n) {
			
			if (n == null) return "";
			return inorder(n.left) +
			n+
			inorder(n.right);
		}

schreiben, oder? Denn so kommen links wieder in fast jeder Zeile die roten "x"-Felder :(
 
Mach das ganze erst mal lesbar, eventuell verstehst es dann auch besser.
Das da oben ist echt mieser Stil ;)

Erstell doch einfach eine Node, diese ist dein Root. Da hängt erst mal nichts dran.

Code:
Node tree = new Node(5, null, null);
Dann gib an was für Child Knoten der Root hat.
Bei dir oben sind die Child Nodes am Root Blätter, also an den Childs hängt nichts weiter dran, d.h. null
Code:
tree.left = new Node(wert, null, null);
tree.right = new Node(wert, null, null);

Nun hast du einen Baum mit Root, linken Child Node, rechten Child node.
Nun musst nur noch darüber iterieren, am besten rekursiv. Dazu gehst du erst links rum bis tree.left == null, danach bis tree.right == null. Ob du inorder, postorder etc. ausgegeben bekommst liegt dann allein daran, an welcher Stelle du dein sysout vom Wert machst. Also Ausgabe des Wertes VOR dem Betreten eines Knotens wäre preorder, beim zurück gehen postorder und inorder direkt nach dem Betreten. das heißt nicht umsonst pre, post, inorder ;D

Levelorder ist dann nimmer so einfach ;)

Diese return Geschichten brauchst du eigentlich gar nicht, außer du willst damit noch hinterher was machen...
if (left == null) return; reicht.
----
Rekursiv musst du dir so vorstellen als ob bei jedem start einer Methode der Methoden Code neu ausgeführt wird. Erst schaut es vom root links ob etwas ist, wenn ja, gehe rein. Dann bist du im linken Child Node. Danach startet die Methode wieder neu und schaut wieder, ist etwas links ? nein, ist etwas rechts ? nein, dann gehe zurück.

Wenn du es dir nicht vorstellen kannst, mach dir in Paint einen Screenshot vom Methoden Code. Bei jedem Rekursiven Aufruf kopierst das Code-Bild und packst es rechts daneben. Im vorherigen Bild markierst du die Stelle an der der rekursive Aufruf erfolgte. Jedes mal wenn die Prüfung fehl schlägt, also Rekursion Abbruch, hakst das Bild ganz rechts ab und betrachtest das Bild links davon. Dort machst du dann an der Markierung weiter. Das dödelst paar mal durch und dann verstehst du wie das genau beim Baum funktioniert. Rekursion ist ein Jojo, es breitet sich aus und rollt zum Schluss zurück.

Beschäftige dich ordentlich damit, sonst könnte das nächste Semester der Genickbrecher werden.
Rekursion ist äußerst wichtig und kommt ständig wieder.
 
Zuletzt bearbeitet:
Beschäftige dich ordentlich damit, sonst könnte das nächste Semester der Genickbrecher werden.
Rekursion ist äußerst wichtig und kommt ständig wieder.
Denn wir sind immer noch kein Hausaufgabenforum.
 
Status
Für weitere Antworten geschlossen.
Zurück
Oben