binärer suchbaum

ETlearner

Mitglied
hallo,
habe wieder mal aufgaben zu erledigen -.-
die aufgabe lautet:
Implementieren Sie einen Datentyp SearchTree<T>, der einen Suchbaum mit Elementen
des generischen Typs T reprasentiert. SearchTree<T> soll die folgenden Eigenschaften
besitzen:
Der Suchbaum entspricht den Spezi kationen:
1. Datenobjekte werden nur in den Blattern gespeichert.
2. Interne Knoten eines Suchbaums besitzen genau zwei Nachfolger.
3. Elemente im linken Teilbaum eines Knotens x sind stets kleiner oder gleich dem
Element von x.
4. Elemente im rechten Teilbaum eines Knotens x sind stets grosser als das Element
von x.
{ Es gibt eine Methode public void insert(int key, T element), die ein neues
Element in den Suchbaum einordnet.
dannach soll ich no eine delete-methode implementieren, welches ein element löscht und eine methode tostring, die alle values der blätter auf der konsole ausgibt. aber soweit bin ich leider noch nicht.

dieser quellcode war schon im tutorium gegeben:
Java:
class BinarySearchTree<T>{
	abstract class Node{
		int key;
		//Konstruktor
		public Node (int key){
		this.key = key;
		}
		public abstract T search(int key); // wird selbst nie aufgerufen, immer ein Objekt vom Typ Fork oder Leaf, die ihre jeweiligen Methoden anwenden
	}

	class Fork extends Node{
		Node leftChild;
		Node rightChild;
		//Konstruktor
		public Fork(int key, Node lc, Node rc){		// Fork ist ein innerer Knoten
		super(key);
		this.leftChild = lc;
		this.rightChild = rc;
	}
		public T search(int key){					
			if (this.key <= key) {
			return rightChild.search(key);
			}
			else { // kleiner gleich immer links lang
			return leftChild.search(key);
			}
		}
	}

	class Leaf extends Node{
		T value;
		//Konstruktor
		public Leaf(int key, T val){
		super(key);
		this.value = val;
		}
		public T search (int key){
		if (this.key == key){
		return this.value;
		}
		else {
		return null;
		}
		}
	}
	
	
	private Node root;
	//Konstruktor
	public BinarySearchTree(){
	this.root = null;
	}

ich habe versucht, die insertmethode zu implementieren...
Java:
	public void insert(int key, T value){
		Node a=root;
		if (root==null){ 
			root=new Leaf(key,value);
		}
		else if(a instanceof Leaf){
			if(key<=a.key){
				root=new Fork(key, new Leaf(key,value), new Leaf(a.key, a.value));
				}
			else{ root=new Fork(a.key,  new Leaf(a.key, a.value), new Leaf(key,value));
			}	
		}
		else{ 
			Node b=a.search(key);
			if(key<=b.key){
				root=new Fork(key, new Leaf(key,value), new Leaf(b.key, b.value));
				}
			else{ root=new Fork(b.key,  new Leaf(b.key, b.value), new Leaf(key,value));
			}
		}
				
	}

ich habe die 3 fälle unterschiede:
baum leer--> wurzel root ist dann übergebener wert
wurzel ist ein Blatt--> vergleichen der schlüssel--> root wird Fork und erhält zwei kindknoten vom typ Leaf

bei der dritten fallunterscheidung komme ich leider nicht so richtig weiter... und ich erhalte fehlermeldungen, die ich nicht beseitigen kann :(

wäre sehr dankbar, wenn ich paar tipps erhalte, wie ich besser vorgehen könnte, da ich immer durcheinanderkomme

lg
 
S

SlaterB

Gast
der erste Tipp ist immer der gleiche:
vergiss Java, schau dir auf dem Papier an was passieren muss,
hast du vielleicht, im Grunde steht es durch die Regeln ja auch schon da,

aber nimm dir ein bestimmtest Beispiel vor, welches du dann auch durch eine main-Methode abbildest und hier postest,
welche Werte willst du in welcher Reihenfolge einfügen? wie genau sieht der Baum jeweils vorher und nachher aus,
was davon leistet dein Code schon (etwa das erste Einfügen?), wo scheitert es und auf welche Weise,
was stellst du das fest oder sagst du dir einfach dass du deinen Code lieber gar nicht erst laufen lässt?

was passiert auf dem Papier genau bei einem bestimmten kritischen Schritt? welche Elemente sind alle neu dabei,
wo gibt es Zeiger/ Links, welche ändern sich zum vorherigen Zustand, hast du schon einen Plan das in Code abzubilden usw.

du kannst locker 3 Seiten und noch mehr schreiben, alles tausendfach im Detail erklären, dabei selber vielleicht lernen,
oder eben nur einen Code schreiben und andere korrigieren lassen? ;)
in Suchmaschinen findest du übrigens sicher beliebig viele fertige Implementierungen

ein Tipp: abgesehen vom ersten if kommt root nur noch begrenzt vor,
durchaus wenn ein neuer Zwischenknoten den vorherigen root ersetzt, aber nicht viermal als ganz normale Anweisung wie in deinem Code
 
Zuletzt bearbeitet von einem Moderator:

ETlearner

Mitglied
habe durch simulationen versucht den quellcode richtig zu implementieren-.- :
Java:
public void insert(int key, T value){
		Node a=root;
		if(root==null){
			root=new Leaf(key, value);
		}
		
		else if(a instanceof Fork){
			if(key <= a.key){
				Node left= new Leaf(key,value);
				Node right= new Leaf(a.key,a.value);
				root= new Fork(key, left, right);
			}
			else{
				Node right= new Leaf(key,value);
				Node left= new Leaf(a.key,a.value);
				root= new Fork(a.key, left, right);
			}
		}
		
		else{
			a=a.search(key);
			if(key <= a.key){
				Node left= new Leaf(key,value);
				Node right= new Leaf(a.key,a.value);
				root= new Fork(key, left, right);
			}
			else{
				Node right= new Leaf(key,value);
				Node left= new Leaf(a.key,a.value);
				root= new Fork(a.key, left, right);
			}

			
		}	
}

leider erhalte ich 6 fehlermeldungen die ich nicht beseitigen kann...
geht die implementierung in die richtige richtung oder ist es wieder mal blödsinn -.-
 
S

SlaterB

Gast
du verzichtest weiter auf jede Zeile Erklärung,

ich kann erkennen dass du weiter root immer überschreibst, den einzigen Punkt den ich angesprochen hatte,
zudem sind die neuen Node-Zeilen eigentlich nur ausgeschriebene Varianten des vorherigen, als du sie jeweils direkt übergeben hattest
([c]root=new Fork(key, new Leaf(key,value), new Leaf(a.key, a.value));[/c])

ich lasse ja mit mir reden, aber das ist bisschen sehr dürftig an Fortschritt ;)
 

ETlearner

Mitglied
Java:
public void insert(int key, T value){
		Node a=root;
		if(root==null){				//bei einem leeren baum setze root als neuen Blatt mit dem jeweiligen schlüssel und wert
			root=new Leaf(key, value);
		}
		
		else if(a instanceof Fork){ // ist root eine instanz von Blatt,so vergleiche key mit dem key von a
			if(key <= a.key){		// wenn key <=a.key, so
				Node left= new Leaf(key,value);	//ist das linke kind ein blatt mit dem schlüssel key und dem wert value und
				Node right= new Leaf(a.key,a.value); // das rechte kind ein blatt mit den eigenschaften von a
				root= new Fork(key, left, right);	// mithilfe des konstruktors werden die kinder an dan elternknoten gebunden
			}
			else{
				Node right= new Leaf(key,value);	// analog
				Node left= new Leaf(a.key,a.value);
				root= new Fork(a.key, left, right);
			}
		}

		
		else{
			a=a.search(key);		// diese zeile ist merke ich grad iwie unlogisch (***)
			if(key <= a.key){		// wenn man an einem blatt angekommen ist, führt man analog zur obigen elseif-implementierung die operationen durch
				Node left= new Leaf(key,value);
				Node right= new Leaf(a.key,a.value);
				a= new Fork(key, left, right);
			}
			else{
				Node right= new Leaf(key,value);
				Node left= new Leaf(a.key,a.value);
				a= new Fork(a.key, left, right);
			}
			
		}
			
			
}

bei (****): kann ich überhaupt das richtige blatt mithilfe der searchmethode finden oder ist die searchmethode dafür nicht geeignet?
und ist die implementierung völlig verkehrt??? root soll ja bei den fällen, dass der baum leer ist oder nur ein element hat verändert werden... oder nicht?
 
Zuletzt bearbeitet von einem Moderator:
S

SlaterB

Gast
du dockterst im Code herum ohne auf das Papier zu schauen,
wenn root leer ist dann ist gut und dann schreibe auch return zum Abbruch um danach nicht zig Zeilen in else schreiben zu müssen,

die erste Aufgabe danach ist das search(),
genau wie du auf Papiert in einem großen Baum mit 5 Ebenen erstmal suchen musst, wo der neue Wert hingehört,

wenn du damit das a bestimmt hast, mag ein Block
Java:
if(key <= a.key){       // wenn key <=a.key, so
                Node left= new Leaf(key,value); //ist das linke kind ein blatt mit dem schlüssel key und dem wert value und
                Node right= new Leaf(a.key,a.value); // das rechte kind ein blatt mit den eigenschaften von a
                root= new Fork(key, left, right);   // mithilfe des konstruktors werden die kinder an dan elternknoten gebunden
            }
            else{
                Node right= new Leaf(key,value);    // analog
                Node left= new Leaf(a.key,a.value);
                root= new Fork(a.key, left, right);
            }
als Grundstruktur genügen, mit root hat das aber nicht unbedingt zu tun wenn du annehmen musst,
dass du dich auf 12 Ebenen tiefer befinden kannst,
speichere den neuen Fork erstmal in einer lokalen Variable,

du musst den nächsthöheren Knoten finden und dort den passenden Nachfolge-Link neu setzen,
vielleicht läßt du auch lieber den vorhandenen Knoten bestehen und änderst den Inhalt, so dass das bisherige a zum Fork wird,
na gut, das geht wohl nicht, ein Leaf kann kein Fork werden, obwohl sogar der key gleichbleiben würde..,

je nach dem ob es keinen nächsthöheren Knoten gibt, kann auch wieder root betroffen sein, da verrate ich nun aber ne Menge,
testet du überhaupt? einen Baum als Beispiel bestimmt auch noch nicht gemalt..

die search()-Methode achtet übrigens überhaupt nicht ob irgendwann mal null kommt, das kann ja kein gutes Ende geben,
eine Rekursion ohne Abbruchbedingung ist immer falsch
 

ETlearner

Mitglied
Java:
if(key <= a.key){       // wenn key <=a.key, so
                Node left= new Leaf(key,value); //ist das linke kind ein blatt mit dem schlüssel key und dem wert value und
                Node right= new Leaf(a.key,a.value); // das rechte kind ein blatt mit den eigenschaften von a
                root= new Fork(key, left, right);   // mithilfe des konstruktors werden die kinder an dan elternknoten gebunden
            }
            else{
                Node right= new Leaf(key,value);    // analog
                Node left= new Leaf(a.key,a.value);
                root= new Fork(a.key, left, right);
            }
als Grundstruktur genügen, mit root hat das aber nicht unbedingt zu tun wenn du annehmen musst,
dass du dich auf 12 Ebenen tiefer befinden kannst,
speichere den neuen Fork erstmal in einer lokalen Variable,

aber in diesem fall soll ja root verändert werden... dieser fall tritt ein, wenn root ein blatt ist. also gibt es keine kinderknoten-> root wird zu einem fork und erhält zwei kinder , die aus der klasse leaf instanziiert wurden
 
S

SlaterB

Gast
wenn du meinst das erkennen zu können, dann bitte,
ich bin mir im Moment gar nicht mehr sicher was deine search-Methode liefert,
überlege doch wirklich was passieren soll wenn etwa der zweite Knoten eingefügt wird,

es muss doch feste Regeln geben nach denen du entscheidest, diese auch umsetzen,
ich verlange jetzt wirklich erst die Regeln, vorher ist doch der Code egal

dass root ein Fork ist wird wohl nicht reichen, wenn root kein Leaf ist, was vielleicht ein interessanter Fall ist, den du vielleicht sogar meinst, wird root immer ein Fork sein
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Cassy3 Binärer Suchbaum Knoten rauslöschen Java Basics - Anfänger-Themen 1
G Java Binärer Suchbaum Java Basics - Anfänger-Themen 1
G Binärer Suchbaum Knoten zählen Java Basics - Anfänger-Themen 1
L Binärer Suchbaum Java Basics - Anfänger-Themen 2
U Binärer Suchbaum delete Java Basics - Anfänger-Themen 1
S Binärer Suchbaum - Size als Variabel in innerer Klasse speichern Java Basics - Anfänger-Themen 2
K Binärer Suchbaum Java Basics - Anfänger-Themen 3
D Binärer Suchbaum Java Basics - Anfänger-Themen 11
Q Binärer suchbaum Java Basics - Anfänger-Themen 2
Y Binärer Suchbaum Java Basics - Anfänger-Themen 5
M Binärer Suchbaum Höhe Java Basics - Anfänger-Themen 6
G Hoffe jemand kann mir ein paar Tips geben:binärer Suchbaum Java Basics - Anfänger-Themen 3
E Binärer Suchbaum Java Basics - Anfänger-Themen 7
R binärer Suchbaum Java Basics - Anfänger-Themen 1
F Aufgabe Rekursion Binärer Baum Java Basics - Anfänger-Themen 15
H binärer String nach int convertieren Java Basics - Anfänger-Themen 3
T Binärer String zu Integer Java Basics - Anfänger-Themen 12
P Binärer Baum mit Composite-Entwurfsmuster Java Basics - Anfänger-Themen 2
S binärer string in negativen int umwandeln Java Basics - Anfänger-Themen 4
C binärer Exponentenbereich bezogen auf das Dezimalsystem Java Basics - Anfänger-Themen 2
G Binärer Baum Java Basics - Anfänger-Themen 3
M Binärer Baum Tiefe Java Basics - Anfänger-Themen 14
T binärer Baum Java Basics - Anfänger-Themen 3
R binärer Baum Java Basics - Anfänger-Themen 2
O Suchbaum Elternknoten finden Level eines Knoten bestimmen Java Basics - Anfänger-Themen 24
N ID3 - Suchbaum ertellen! Java Basics - Anfänger-Themen 0
M Suchbaum implementieren Java Basics - Anfänger-Themen 8
C Methoden Methode zu einem Binären Suchbaum Java Basics - Anfänger-Themen 8
J Suchbaum Java Basics - Anfänger-Themen 3
B Datentypen Suchbaum - Rekursive Ausgabe Java Basics - Anfänger-Themen 1
N Binären Suchbaum erstellen, nachzuvollziehen Java Basics - Anfänger-Themen 0
W binären Suchbaum Kantenanzahl Java Basics - Anfänger-Themen 3
G Rekursion Suchbaum Java Basics - Anfänger-Themen 2
W Löschen Datenknoten Suchbaum Java Basics - Anfänger-Themen 4
H Suchbaum iterativ absteigen? Java Basics - Anfänger-Themen 3
N Tiefe im binären Suchbaum Java Basics - Anfänger-Themen 9
I Rekursives Löschen in Binärem Suchbaum Java Basics - Anfänger-Themen 2
A Suchbaum Java Basics - Anfänger-Themen 4
DasDogma Suche im Suchbaum Java Basics - Anfänger-Themen 2
D suchbaum out of heap space Java Basics - Anfänger-Themen 8
G Binäre Suchbaum + Erstellung des Programmes Java Basics - Anfänger-Themen 4
Bierhumpen Suchbaum problem. Java Basics - Anfänger-Themen 8

Ähnliche Java Themen

Neue Themen


Oben