Binärbaum - Problem bei Knoten anhängen / löschen

mazaka

Neues Mitglied
Hallo,

ich habe ein Problem beim Anhängen eines Knotens. Bisher werden komischerweise nur Zahlen von 1-9 korrekt dargestellt. Es sollen aber alle positiven sowie negativen Zahlen dargestellt werden können. Zahlen die größer als der vorangegangene Knoten sind, müssen rechts abgebildet werden und kleinere Zahlen links.

baumausgabe.png

Das Löschen eines Endknotens funktioniert problemlos (Zahlen 2, 6, 8), wenn jedoch die Zahl 7 löscht, tritt ein "NullPointerException" auf. In diesem Bsp. sollte jeweils der längste Zweig nachrutschen, in diesem Fall die 9 ersetzt die 7. Sind beide Zweige gleich lang, dann soll der größere Wert nachrutschen.

Kann mir dabei jemand aus der Community vielleicht helfen? Komme da leider nicht weiter.

Danke schonmal im Voraus!


Node.java
Java:
 package binaerbaum2;
import java.io.Serializable;

import java.util.List;

public class Node implements Serializable{
    private Node left;
    private Node right;
    private Integer value;

    public Node(Integer value) {
        this.value = value;
    }

    /**
     * @return the UebergabeObjekt
     */
    public Integer getValue() {
        return value;
    }

    @Override
    public String toString() {
        return value.toString();
    }

    public boolean add(int thatValue) {
        int result = BinaryTree.comparator.compare(this.value, thatValue);
        System.out.println(result);
        if(result == 0) { //Objekt bereits vorhanden - tue nichts
            return false;
        } else if(result > 0) { //Objekt ist größer -> rechter Sohn
            if (right == null) {
                right = new Node(thatValue);
                return true;
            } else {
                return right.add(thatValue);
            }
        } else { //Objekt ist kleiner -> linker Sohn
            if (left == null) {
                left = new Node(thatValue);
                return true;
            } else {
                return left.add(thatValue);
            }
        }
    }

    public int getDepth() {
        int leftDepth = left == null ? 0 : left.getDepth();
        int rightDepth = right == null ? 0 : right.getDepth();
        return 1 + Math.max(leftDepth, rightDepth);
    }

    public boolean delete(int thatValue) {
        int result = BinaryTree.comparator.compare(this.value, thatValue); 
        if(result == 0) { //Objekt gefunden - löschen
            if (left == null && right == null) {
                value = null;
            } else if (left != null && (right == null || Math.random() < 0.5)) {
                value = left.getValue();
                left = left.left;
                right = left.right;
            } else {
                value = right.getValue();
                left = right.left;
                right = right.right;
            }
            return true;
        } else if(result > 0) { //Objekt ist größer -> rechter Sohn
            if (right == null) {
                System.out.println("\nKnoten konnte nicht gefunden werden.");
                return false;
            } else {
                 if(right.delete(thatValue)) {
                     if (right.getValue() == null) {
                         right = null;
                     }
                     return true;
                 } else {
                     return false;
                 }
            }
        } else { //Objekt ist kleiner -> linker Sohn
             if(left == null) {
                 return false;
             } else {
                 if(left.delete(thatValue)) {
                     if (left.getValue() == null) {
                         left = null;
                     }
                     return true;
                 } else {
                     return false;
                 }
            }
        }
    }

    void display(StringBuilder sb, String upperPrefix, String prefix, String lowerPrefix) {
        if (left != null) {
          left.display(sb,  upperPrefix + "   ", upperPrefix + "/--",  upperPrefix + "|  ");
        }
        sb.append(prefix).append(value).append('\n');
        if (right != null) {
          right.display(sb, lowerPrefix + "|  ", lowerPrefix + "\\--", lowerPrefix + "   ");
        }
    }

    void toList(List<Object> result) {
        if(left != null) {
            left.toList(result);
        }
        result.add(value);
        if(right != null) {
            right.toList(result);
        }
    }

}

BinaryTreeTest.java
Java:
package binaerbaum2;

import java.io.*;
import java.util.*;

public class BinaryTreeTest {
    BinaryTree binearTree;
    private final int ANHAENGEN = 1;
    private final int ENTFERNEN = 2;
    private final int BAUMAUSGABE = 3;
    private final int SPEICHERN = 4;
    private final int LADEN = 5;

    private final int ENDE = 9;
    private int wert;
    private Scanner scanner = new Scanner(System.in);

    public BinaryTreeTest() {
    }

    public void start() {
        int menueAuswahl = -1;
        binearTree = new BinaryTree();
         
        do {
            System.out.println("<<<<<<<<<<<<< M E N U E >>>>>>>>>>>>");
            System.out.println("** Bitte treffen Sie eine Auswahl **");
            System.out.println("<<<<<<<<<<<<<<<<< >>>>>>>>>>>>>>>>>>");
            try {
                menueAuswahl  = auswaehlen();
                switch (menueAuswahl) {
                    
                case ANHAENGEN:
                    System.out.print("Bitte Zahl eingeben: ");
                    wert = scanner.nextInt();
                    binearTree.add(wert);
                    break;

                case ENTFERNEN:
                    System.out.print("Bitte Zahl eingeben: ");
                    wert = scanner.nextInt();
                    binearTree.delete(wert);
                    break;

                case BAUMAUSGABE:
                    System.out.println("<<<<<<<<<<<<<<<<< >>>>>>>>>>>>>>>>>>");
                    System.out.println("         B A U M A U S G A B E");
                    System.out.println("<<<<<<<<<<<<<<<<< >>>>>>>>>>>>>>>>>>\n");
                    System.out.println(binearTree.toString());
                    break;

                case LADEN:
                    System.out.println("\n******** Binärbaum einlesen ********");
                    this.deserialize("binaerbaum.txt");
                    break;

                case SPEICHERN:
                    System.out.println("\n******** Binärbaum speichern *******");
                    this.serialize("binaerbaum.txt");
                    break;

                case ENDE:
                    break;
                default:
                    System.out.println("\n************************************");
                    System.out.println("Bitte eine gültige Eingabe machen.");
                    System.out.println("************************************\n");
                }
            } catch (Exception e) {
                e.printStackTrace();
                menueAuswahl = ENDE;
            }
        } while (menueAuswahl != ENDE);

    }

    public int auswaehlen() {
        System.out.print(
         "*** Taste " + ANHAENGEN + ": Knoten anhaengen ******\n" +
         "*** Taste " + ENTFERNEN + ": Knoten entfernen ******\n" +
         "*** Taste " + BAUMAUSGABE + ": Binärbaum ausgeben ****\n" +
         "*** Taste " + SPEICHERN + ": Binärbaum speichern ***\n" +
         "*** Taste " + LADEN + ": Binärbaum laden *******\n" +
         "*** Taste " + ENDE + ": Programm beenden. *****\n");
        System.out.println("<<<<<<<<<<<<<<<<< >>>>>>>>>>>>>>>>>>");
        System.out.print("Eingabe: ");
        return scanner.nextInt();
    }


         public void serialize(String filename){

	try{
	      FileOutputStream file = new FileOutputStream( filename );
	      ObjectOutputStream o = new ObjectOutputStream( file );
	      o.writeObject(this.binearTree);
	      o.close();
	      System.out.println("Baum in binaerbaum.txt gespeichert.");
              System.out.println("************************************\n");
	    }catch ( IOException e ) {
	    	System.err.println( e );
	    }
	}

	void deserialize( String filename ){

            try{
              
	      FileInputStream file = new FileInputStream( filename );
	      ObjectInputStream o = new ObjectInputStream( file );

	      this.binearTree  = (BinaryTree) o.readObject();
	      o.close();
	      System.out.println("Baum wurde erfolgreich eingelesen.");
              System.out.println("************************************\n");
               
	    }
	    catch ( IOException e ) {
	    	System.err.println( e );
	    }
	    catch ( ClassNotFoundException e ) {
	    	System.err.println( e );
	    }
	  }

    public static void main(String[] args) {
        try {
            BinaryTreeTest testlauf = new BinaryTreeTest();
            System.out.println("***********************************");
            System.out.println("       B I N A R Y   T R E E");
            System.out.println("***********************************");
            System.out.println("     S O R T E D   E D I T I O N");
            System.out.println("-----------------------------------");
            System.out.println("               V. 1.0\n");
            testlauf.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

BinaryTree.java
Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package binaerbaum2;
import java.io.Serializable;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class BinaryTree implements Serializable {

    private Node root;
    public static Comparator<Integer> comparator = new Comparator<Integer>(){

        public int compare(Integer o1, Integer o2) {
            return o1.toString().compareTo(o2.toString());
        }
    };

    private int size;

    /**
     * Hinzuefuegen von Objekten
     *
     * @param uebergabeObjekt
     *            Das uebergeben Object
     */
    public void add(int value) {
        if (root == null) {
            root = new Node(value);
            size ++;
        } else {
            if(root.add(value)) {
               size++;
            }
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        if (root != null) {
            StringBuilder sb = new StringBuilder();
            root.display(sb, "","","");
            return sb.toString();
        } else {
            return "<leerer Baum>";
        }
    }

    public List<Object> toList() {
        List<Object> result = new ArrayList<Object>();
        if (root != null) {
            root.toList(result);
        }
        return result;
    }

    /**
     * @return the anzahlKnoten
     *
     */
    public int getSize() {
        return size;
    }

    /**
     * Loescht ein uebergebenes Object
     *
     * @param uebergabe
     *            Das yu loeschende Object
     */
    public void delete(Integer value) {
        if (root != null) {
            if (root.delete(value)) {
                size--;
            }
            if (root.getValue() == null) {
                root = null;
            }
        }
    }

    /**
     * @return the gesamtEtagen
     */
    public int getDepth() {
        if(root == null) {
            return 0;
        } else {
            return root.getDepth();
        }
    }
}
 
S

SlaterB

Gast
dein Comparator vergleicht nach Strings, 12 ist also kleiner als 2, ist das sinnvoll?
ansonsten werden bei mir auch Zahlen > 9 eingefügt,

zum Löschen:
Java:
            } else if (left != null && (right == null || Math.random() < 0.5)) {
                value = left.getValue();
                left = left.left;
                right = left.right;
left ist vielleicht != null, der value wird nach this übernommen, gerne,
dann setzt du aber left auf left.left, was doch null sein kann, wird nicht überprüft,
von diesem möglichen null fragst du dann right ab -> BOOM

die letzte Zeile meint vielleicht eher, das right das right vom alten left sein soll?
aber das alte left hast du im Moment gar nicht mehr, die Variable ist ja schon überschrieben,
an dieser Stelle kann Vertausch der Zeilen helfen,
allgemein robuster ist es, das alte left in einer Variablen temp zu speichern oder ähnliches
 

Gadolfo

Neues Mitglied
Hallo,

sicher werden auch Zahlen größer 9 eingefügt ;), das ist nicht das Problem ... bloß wie diese eingefügt werden. Beginnst Du mit einer 5 und fügst danach eine 12 ein wird diese links eingefügt vom Baum statt rechts. Wie Du schon angesprochen hast liegt es sicherlich daran dass der Comp. 12 < 2 ... bloß wie ließe sich das umgehen?

Das löschen funktioniert leider auch dann nicht für die Knoten an denen mehrere Knoten hängen, wenn man an der Stelle die Variable vertauscht.
 

Gadolfo

Neues Mitglied
Danke Slater, Du bist ein GENIE!!! :)

Zwecks Löschen habe ich jetzt die Zeilen vertauscht, dies führt dazu, dass Werte gelöscht werden können, auch wenn mehrere Knoten noch dahinterhängen - und das ohne Nullpointer-Exception. Leider löscht er aber auch, wenn an einem Knoten links und rechts weitere Knoten hängen, die andere Seite komplett mit.

Code:
public boolean delete(int thatValue) {
        int result = BinaryTree.comparator.compare(this.value, thatValue); 
        if(result == 0) { //Objekt gefunden - löschen
            if (left == null && right == null) {
                value = null;
            } else if (left != null && (right == null || Math.random() < 0.5)) {
                value = left.getValue();
                right = left.right;
                left = left.left;
                
            } else {
                value = right.getValue();
                left = right.right;
                right = right.right;
             
                
            }
            return true;
        } else if(result > 0) { //Objekt ist größer -> rechter Sohn
            if (right == null) {
                System.out.println("\nKnoten konnte nicht gefunden werden.");
                return false;
            } else {
                 if(right.delete(thatValue)) {
                     if (right.getValue() == null) {
                         right = null;
                     }
                     return true;
                 } else {
                     return false;
                 }
            }
        } else { //Objekt ist kleiner -> linker Sohn
             if(left == null) {
                 return false;
             } else {
                 if(left.delete(thatValue)) {
                     if (left.getValue() == null) {
                         left = null;
                     }
                     return true;
                 } else {
                     return false;
                 }
            }
        }
    }

Beispiel:

7 soll gelöscht werden. 9 - 11 müssen nachrücken. 6 sollte nach Löschen an 9 hängen.
33c9742.png


9 - 11 rutschen nach, 6 wird leider gelöscht.
312e783.png


Kann man das umgehen?
 
S

SlaterB

Gast
Java:
            } else {
                value = right.getValue();
                left = right.right;
                right = right.right;
zweimal right.right?
obwohl das nicht ganz zur Ausgabe passt, müsste dann nicht die 11 zweimal im Baum vorkommen?
na du kannst dir die Stelle doch ganz exakt anschauen, was steht vorher/während/nachher in allen Variablen,
mit System.out.println ist alles zu klären, arbeite ein bisschen statt immer nur zu fragen
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Y Wie greift man auf die Knoten in einem Binärbaum zu? Java Basics - Anfänger-Themen 5
T Binärbaum-Suche Implementation Java Basics - Anfänger-Themen 6
A Binärbaum rekursiv durchsuchen und Referenz zurückgeben Java Basics - Anfänger-Themen 4
D Werte aus einem BinärBaum in einem Array speichern Java Basics - Anfänger-Themen 1
D Binärbaum Blätter finden und Ausgeben Java Basics - Anfänger-Themen 22
O BinärBaum einfügen Java Basics - Anfänger-Themen 13
E Erste Schritte Testklasse Binärbaum Java Basics - Anfänger-Themen 10
void19 Methoden Binärbaum Inorder Traversierung in Array speichern Java Basics - Anfänger-Themen 1
A Größten Eintrag aus Binärbaum löschen Java Basics - Anfänger-Themen 4
L Ganzen BinärBaum ausgeben? Java Basics - Anfänger-Themen 3
L Binärbaum (Stammbaum) Java Basics - Anfänger-Themen 8
S Binärbaum in PreOrder in ArrayList speichern Java Basics - Anfänger-Themen 0
J Methoden Binärbaum, Traversierung in Array speichern Java Basics - Anfänger-Themen 18
K BinärBaum Java Basics - Anfänger-Themen 4
J Max. Anzahl von Knoten im Binärbaum Java Basics - Anfänger-Themen 3
M Werte der Knoten in Binärbaum addieren (iterativ) Java Basics - Anfänger-Themen 6
C Binärbaum mit grafischer Ausgabe Java Basics - Anfänger-Themen 0
J Binärbaum formatiert ausgeben. Java Basics - Anfänger-Themen 7
P Listen sortieren mit Binärbaum gibt keine Ausgabe ab 10000 Integern Java Basics - Anfänger-Themen 14
E Binärbaum - von rekursiv zu iterativ Java Basics - Anfänger-Themen 10
W Größtes Element im unsortierten Binärbaum Java Basics - Anfänger-Themen 7
N Generischer Binärbaum - löschen Java Basics - Anfänger-Themen 1
M Binärbaum mit parent-Zeigern Java Basics - Anfänger-Themen 1
B Methoden BinärBaum als String Knoten löschen Java Basics - Anfänger-Themen 5
S Binärbaum kopieren Java Basics - Anfänger-Themen 6
B Binärbaum mit java implementieren! Java Basics - Anfänger-Themen 5
D Binärbaum Suche Java Basics - Anfänger-Themen 5
D Binärbaum probleme Java Basics - Anfänger-Themen 4
P Binärbaum - Primärschlüssel Java Basics - Anfänger-Themen 3
X Fehler Binärbaum Java Basics - Anfänger-Themen 6
PaulG Fragen zu Binärbaum Java Basics - Anfänger-Themen 21
N Binärbaum/Implementierung Java Basics - Anfänger-Themen 9
P Binärbaum Ordnungsproblem Java Basics - Anfänger-Themen 8
P Generischer Binärbaum (compareTo Frage) Java Basics - Anfänger-Themen 4
P einen binärbaum implementieren Java Basics - Anfänger-Themen 4
B Binärbaum höhe herausfinden Java Basics - Anfänger-Themen 12
L Rot Scharz Baum von Binärbaum erben Java Basics - Anfänger-Themen 9
S Klassen Aufgabe: Binärbaum überprüfen Java Basics - Anfänger-Themen 16
S Binärbaum Java Basics - Anfänger-Themen 9
S Variable Parameterliste in Binärbaum Java Basics - Anfänger-Themen 2
N BinärBaum Hilfestellung Java Basics - Anfänger-Themen 8
S Binärbaum prüfen, ob sortiert oder unsortiert Java Basics - Anfänger-Themen 6
W Binärbaum zahlen addieren Java Basics - Anfänger-Themen 7
S Binärbaum - Klasse Knoten - Methode Suchen Java Basics - Anfänger-Themen 5
S Binärbaum Java Basics - Anfänger-Themen 7
I Binärbaum Java Basics - Anfänger-Themen 5
S Bitte um Hilfe beim unsortierten Binärbaum!! Java Basics - Anfänger-Themen 6
J Binärbaum getSize Java Basics - Anfänger-Themen 4
P Fragen zum Binärbaum Java Basics - Anfänger-Themen 3
S Binärbaum implementieren Java Basics - Anfänger-Themen 6
K Tiefe im Binärbaum Java Basics - Anfänger-Themen 2
G generischer binärbaum Java Basics - Anfänger-Themen 9
G Binärbaum und Wrapperklassen Java Basics - Anfänger-Themen 6
F Binärbaum codieren. Codeproblem! Java Basics - Anfänger-Themen 4
D rekursion im binärbaum Java Basics - Anfänger-Themen 11
0 Binärbaum als verkettete Liste Java Basics - Anfänger-Themen 3
T Binärbaum - noch ein "klitzekleiner Fehler" Java Basics - Anfänger-Themen 4
B Binärbaum auf Vollständigkeit prüfen Java Basics - Anfänger-Themen 15
G Frage zur einfügen in einem Binärbaum Java Basics - Anfänger-Themen 21
G Binärbaum grafisch darstellen Java Basics - Anfänger-Themen 4
K Verständnis Problem bei Server/Client Java Basics - Anfänger-Themen 2
I WildFily - unterschiedliche Libs im Projekt verursachen Problem Java Basics - Anfänger-Themen 11
imocode Vererbung Problem mit Vererbung Java Basics - Anfänger-Themen 2
L Taschenrechner Problem Java Basics - Anfänger-Themen 4
I Applikationsserver (WildFly) - Zugriff auf Ressourcen.. Problem mit Pfade Java Basics - Anfänger-Themen 10
A ScheduledExecutorService problem Java Basics - Anfänger-Themen 7
marcelnedza Problem mit Weltzuweisung, JavaKarol Java Basics - Anfänger-Themen 13
XWing Methoden rückgabe Problem? Java Basics - Anfänger-Themen 6
M Erste Schritte Collatz Problem max int Java Basics - Anfänger-Themen 3
M Problem bei verschachtelter for-Schleife bei zweidimensionalen Arrays Java Basics - Anfänger-Themen 3
C GLOOP Problem beim Erstellen der Kamera Java Basics - Anfänger-Themen 9
nelsonmandela Problem bei Ausgabe einer Switch - Case Funktion Java Basics - Anfänger-Themen 5
frager2345 Problem mit Methode Java Basics - Anfänger-Themen 4
L Problem bei Rechnung mit Math.pow Java Basics - Anfänger-Themen 13
A Thread-Schreibe-Lese-Problem Java Basics - Anfänger-Themen 4
SUPERTJB return Problem Java Basics - Anfänger-Themen 3
sserio BigInteger Problem Java Basics - Anfänger-Themen 4
JordenJost Taschenrechner problem Java Basics - Anfänger-Themen 5
K Problem mit "Random" Java Basics - Anfänger-Themen 5
S Datei anlegen Problem! Groß- und Kleinschreibung wird nicht unterschieden Java Basics - Anfänger-Themen 4
sserio Problem beim Anzeigen Java Basics - Anfänger-Themen 5
xanxk Problem For-Schleife mit Charakter Java Basics - Anfänger-Themen 2
L Unbekanntes Problem mit 2d Array Java Basics - Anfänger-Themen 6
sserio Liste erstellt und ein Problem mit dem Index Java Basics - Anfänger-Themen 8
sserio Schwimmen als Spiel. Problem mit to String/ generate a card Java Basics - Anfänger-Themen 4
J Schleife Problem Java Basics - Anfänger-Themen 2
D Problem mit der Erkennung von \n Java Basics - Anfänger-Themen 2
milan123 das ist meine aufgabe ich hab das problem das bei mir Wenn ich die Richtung der Linien verändern will und drei davon sind richtig, verändere ich die 4 Java Basics - Anfänger-Themen 3
M Verständins Problem bei Aufgabe Java Basics - Anfänger-Themen 4
HeiTim Problem mit der Kommasetzung an der richtigen stelle Java Basics - Anfänger-Themen 59
Temsky34 Problem mit dem Code Java Basics - Anfänger-Themen 17
P Problem mit Calendar.getDisplayName() Java Basics - Anfänger-Themen 8
C Problem mit mehreren Methoden + Scanner Java Basics - Anfänger-Themen 5
P Datei einlesen, nach Begriff filtern und in Datei ausgeben. Problem Standardausgabe über Konsole Java Basics - Anfänger-Themen 19
M Problem mit Klassenverständnis und Button Java Basics - Anfänger-Themen 8
EchtKeineAhnungManchmal hallo habe ein Problem mit einer Datei -> (Zugriff verweigert) Java Basics - Anfänger-Themen 4
H Problem mit Verzweigungen Java Basics - Anfänger-Themen 6
H Problem mit Rückgabewert Java Basics - Anfänger-Themen 7
josfe1234 JAVA FX problem Java Basics - Anfänger-Themen 3
A Code Problem Java Basics - Anfänger-Themen 6

Ähnliche Java Themen

Neue Themen


Oben