OOP Über einen AVL-Baum iterieren (NullPointer)

Butterbrot

Aktives Mitglied
Guten Abend Community,

momentan schreibe ich an einem binären Suchbaum, über den ich iterieren möchte. Sobald ich aber meinen Iterator, der nach der Tiefensuche iteriert, ausführe erhalte ich eine NullPointerException. Dieser Nullpointer ergibt sich, sobald ich in der Zeile "stack.push(current)", also tippe ich darauf, dass mein "current" nichts ist. Sobald ich aber anstatt dem Startwert, die Wurzel "root" am Anfang der Klasse verwende, erhalte ich ebenfalls einen NullPointer. Nun ist meine Frage, mit was ich meinen Startwert nun instanziieren muss oder ob mein Ansatz generell falsch ist? Generell habe ich etwas Schwierigkeiten den Iterator zu schreiben und wäre über jegliche Tipps und Anregungen sehr dankbar. Ich habe folgende Klasse geschrieben und habe zwar nur mit der Iterator()-Methode ein paar Probleme, dennoch poste ich die gesamte Klasse, damit sich Fragen im Vorfeld ergeben sollten bzw. man die Struktur besser erkennen kann. Danke im Voraus :)

Java:
public class AuDTree<E extends Comparable<? super E>> implements AuDTreeInterface<E> {

    private class Node{

        public Node left;
        public Node right;
        public Node parent;
        public E value;

        public Node(E value){
            left = null;
            right = null;
            parent = null;
            this.value = value;
        }

    }

    public Node root;

    public AuDTree(){
        this.root = null;
    }


    @Override
    public boolean isEmpty() {
        if(root == null){
            return true;
        }
        else{
            return false;
        }

    }

    @Override
    public int count() {

        return count(root);

    }

    private int count(Node n) {
        if (n == null) return 0; 
        else { 
            int l = 1;
            l += count(n.left); 
            l += count(n.right); 
            return l; 
        }

    }

    @Override
    public int getHeight() {
        return getHeight(root);
    }

    private int getHeight(Node n) {
        if (n == null) {
            return -1;
        }
        return Math.max(getHeight(n.left), getHeight(n.right)) + 1;
    }

    @Override
    public boolean isAVLTree() {
        return isAVLTree(root);

    }

    public boolean isAVLTree(Node n){

        if(root == null) return true;

        if(root.value.compareTo(getMinValue()) <= 0 || root.value.compareTo(getMaxValue()) >=0) {
            return false;
        }

        else{
            if(n.left != null)isAVLTree(n.left);
            if(n.right != null)isAVLTree(n.right);

            if(getHeight(n.left) - getHeight(n.right) > 1 || getHeight(n.right) - getHeight(n.left) > 1 ){
                return false;
            }
            return true;

        }

    }

    @Override
    public boolean contains(E value) {

        if(isEmpty()) return false;
        else{
            Node current = root;

            while (current != null) {
                int comparison = value.compareTo(current.value);
                if (comparison == 0) {
                    return true;
                } else if (comparison < 0) {
                    current = current.left;
                } else { //comparison > 0
                    current = current.right;
                }
            }

            return false;
        }

    }

    @Override
    public void insert(E value) throws ElementExistsException {
        if(contains(value)) throw new ElementExistsException();
        else{
            if(root == null) root = new Node(value);
            else{
                Node father = null;
                Node k = root;
                while(k != null){
                    father = k;
                    if(value.compareTo(k.value) < 0){
                        k = k.left;
                    }
                    else{
                        if(value.compareTo(k.value) > 0){
                            k = k.right;
                        }
                    }
                }

                if(value.compareTo(father.value) < 0){
                    father.left = new Node(value);
                }
                else{
                    father.right = new Node(value);
                }
            }
        }
    }


    @Override
    public void remove(E value) throws ElementExistsException {
        if(!contains(value)) throw new ElementExistsException("Gibts nicht!");
        else{
            Node node = finds(value);
            node = deleteNode(node);
        }
    }

    private Node deleteNode(Node node){

        Node newNode = node;

        if(node.left == null && node.right == null) newNode = null;
        else if(node.left != null && node.right == null) newNode = node.left;
        else if(node.left == null && node.right != null) newNode = node.right;
        else{
            if(quantityofchildren(biggest(node.left)) == 0){
                newNode = biggest(node.left);
            }
            else{
                Node secondNode = node;
                newNode = biggest(node.left);
                secondNode = biggest(node.left).left;
            }

        }

        return node;
    }

    private Node finds(E value){

        Node current = root;

        while (current != null) {
            int comparison = value.compareTo(current.value);
            if (comparison == 0) {
                return current;
            } else if (comparison < 0) {
                current = current.left;
            } else { //comparison > 0
                current = current.right;
            }
        }

        return current;

    }

    private int quantityofchildren(Node node){

        return getHeight(node);
    }

    private String leftorrightchildren(Node node){

        if(node.value.compareTo(node.parent.value) > 0) return "right";
        else return "left";
    }

    private Node biggest(Node node){

        Node start = node;

        while(start.right != null){
            start = start.right;
        }

        return start;

    }

    private E smallest(Node node){

        Node start = node;

        while(start.left != null){
            start = start.left;
        }

        return start.value;
    }


    @Override
    public Iterator<E> iterator() {

        return new Iterator<E>(){
            Node start;
            Node current;
            int counter;
            Stack<Node> stack;

            public void iterator() {
                start = new Node(null);
                counter++;
                stack = new Stack<Node>();
                current = start;
                stack.empty();
            }
           
            @Override
            public boolean hasNext() {
                if(counter == count(root)) return false;
                else return true;
            }

            @Override
            public E next() {
                stack.push(current);
                counter++;
                if(current.left.value != null) return current.left.value;
                else return current.right.value;
            }

        };
    }

    @Override
    public Iterator<E> iteratorBFS() {
        return new Iterator<E>(){

            @Override
            public boolean hasNext() {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public E next() {
                // TODO Auto-generated method stub
                return null;
            }

        };
    }

    @Override
    public E getMinValue() {

        Node node = root;

        while(node.left != null){
            node = node.left;
        }

        return node.value;
    }

    @Override
    public E getMaxValue() {

        Node node = root;

        while(node.right != null){
            node = node.right;
        }

        return node.value;
    }



    public static void main(String[] args) {

        AuDTree<Integer> a = new AuDTree<Integer>();
        a.insert(3);
        a.insert(2);
        a.insert(4);
        a.insert(1);
        a.insert(0);
        //        System.out.println(a.finds(4));
        //        a.insert(5);
        //        a.insert(4);
        //        a.insert(3);


        //        System.out.println(a.count());
        //        System.out.println(a.contains(3));
        //        System.out.println(a.getHeight());
        //        System.out.println(a.contains(10));
        //        System.out.println(a.isAVLTree());
        //        System.out.println(a.getMinValue());
        //        System.out.println(a.getMaxValue());

        //        a.remove(0);

        for(Integer element : a){
            System.out.println(element);
        }
    }
}
 

bene2808

Aktives Mitglied
Wird denn die Methode iterator() zum Initialisieren des Iterators irgendwo aufgerufen...?

Und zum Ansatz: Wenn eines der Enden des Baums erreicht wird, also wenn der aktuelle Knoten weder linken noch rechten Nachfolger hat, musst du wieder nach oben.
 

bene2808

Aktives Mitglied
Naja der Iterator scheint, wie du sagst, nach der Tiefensuche in die Tiefe zu gehen, aber von da kommt er nicht mehr raus, um auch noch die anderen Zweige des Baums abzuklappern. Wenn also tatsächlich beide Nachfolger des aktuellen Knotens null sind, musst du am besten in einer Schleife die Struktur wieder so weit nach oben gehen, bis du einen Knoten findest, an dem du einen Zweig noch nicht durchsucht hast (das ist dann wenn dann der rechte, wenn du immer mit dem linken beginnst; hier musst du aber darauf achten, dass du nicht bereits aus dem rechten kommst: sollte dies der Fall sein musst du weiter nach oben).

Zur NullPointerException: Du definierst eine Methode iterator() in deiner lokalen Iterator-Klasse, die aber (oder habe ich etwas übersehen???) nirgends aufgerufen wird. Entsprechend sind die Objekte des Iterators nicht initialisiert und die stack-Variable ist null.

Noch ein paar andere Verbesserungsvorschläge:
In hasNext() rufst du count(Node) auf. Das geschieht dann in jedem Schleifendurchlauf, was bei großen Bäumen sehr ineffizient wäre. Wenn du davon ausgehst, dass sich der Baum während des Iterierens nicht ändert, wäre es hier sinnvoller, die Anzahl einmal zu berechnen und als Integer zu speichern.

Außerdem implementierst du einen Baum. Wie wäre es da mit dem Design Pattern Kompositum mit einem Abschluss-Knoten? Einfach mal googeln, sofern du dich nicht bewusst dagegen entschieden hast;)
 

Butterbrot

Aktives Mitglied
Also erst einmal danke für die umfangreiche und informierende Antwort. Tut mir leid, dass ich erst jetzt antworte, ich hatte gestern leider noch etwas anderes zu tun. Also ich hab den Code jetzt umgeändert in:
Java:
@Override
    public Iterator<E> iterator() {

        return new Iterator<E>(){
            Node start;
            Node current;
            int counter;
            Stack<Node> stack;
            int border = count(root);

            public void iterator() {

                start = new Node(null);
                counter++;
                stack = new Stack<Node>();
                current = start;
                stack.empty();
            }

            @Override
            public boolean hasNext() {
                if(counter == border) return false;
                else return true;
            }

            @Override
            public E next() {
                stack.push(current);
                counter++;
                if(current.left.value != null) return current.left.value;
                else if(current.right.value != null) return current.right.value;
                else if(current.left == null && current.right == null){
                    while(current.right != null){
                        current = current.parent;
                    }
                    //                    return current.value;
                }
                return current.value;
            }

        };
    }

Könntest du mir noch bitte einen Beispiel-Code senden, was du denn genau damit meinst, dass ich den Iterator aufrufen soll.

P.S.: Pattern Design Kompositum haben wir in den Vorlesungen nicht gelernt und müssen wir auch nicht anwenden :)
 

Butterbrot

Aktives Mitglied
Okay nein, passt schon danke. Ich habs mittlerweile selber hingekriegt. Falls später noch jemand auf diesen Forum-Beitrag stoßen sollte hier der Code:

Java:
@Override
    public Iterator<E> iterator() {

        return new Iterator<E>(){
            Node current;
            Stack<Node> stack;

            {   
                stack = new Stack<Node>();
                current = root;
                stack.add(root);
            }

            @Override
            public boolean hasNext() {
                if(stack.empty()) return false;
                else return true;
            }

            @Override
            public E next() {
                if(!hasNext()){
                    throw new NoSuchElementException();
                }
                Node n = stack.pop();
                if(n.left != null) stack.push(n.left);
                if(n.right != null) stack.push(n.right);

                return    n.value;           
            }

        };
    }
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Über einen Button etwas zeichnen lassen Java Basics - Anfänger-Themen 5
Ray19941 Über BlueJ Textdatei selbstständig erstellen lassen Java Basics - Anfänger-Themen 2
C Methoden Über eine einfach verkettete Liste Java Basics - Anfänger-Themen 8
B OOP Über eine doppelt verkettete Liste iterieren Java Basics - Anfänger-Themen 4
O Über Map laufen Erklärung Java Basics - Anfänger-Themen 4
U Best Practice Buttons sollen ÜBER Labeln liegen, also quasi im Vordergrund. WIE? Java Basics - Anfänger-Themen 4
AssELAss Über ein Objekt vom Typ BigDecimal iterieren Java Basics - Anfänger-Themen 6
L Über 100e Werte anzeigen Java GUI Java Basics - Anfänger-Themen 1
0 Über CMD die JAVA Datei ausführen? möglich? Java Basics - Anfänger-Themen 8
A Über Jahr iterieren, Freitag der 13. Java Basics - Anfänger-Themen 2
S Über Button Zeichnung ändern Java Basics - Anfänger-Themen 5
G Erste Schritte Über verschiedene Datentypen iterieren. Gibt es sowas? Java Basics - Anfänger-Themen 19
J Über ... Dialog (Mac OS) Java Basics - Anfänger-Themen 8
L Über abstrakte Klasse auf eine Klasse zugreifen? Java Basics - Anfänger-Themen 6
PINTOR Über IP verschicken Java Basics - Anfänger-Themen 3
D Über ein Interface methoden ansprechen Java Basics - Anfänger-Themen 9
C Über Boolean Static, String ausgeben Java Basics - Anfänger-Themen 3
S Über Bild zeichnen Java Basics - Anfänger-Themen 21
H Mac Menu-Über Programm anpassen Java Basics - Anfänger-Themen 3
K Datentypen Über Collection iterieren bringt fehler Java Basics - Anfänger-Themen 8
P Über HashMap iterieren -> NullPointerException Java Basics - Anfänger-Themen 2
J Array List - Über die Konsole eingeben Java Basics - Anfänger-Themen 1
A Struts: Über Collection iterieren mir Taglibs? Java Basics - Anfänger-Themen 13
G Über Button DB Tabelleninhalt löschen Java Basics - Anfänger-Themen 24
G Über undo, copy, cat, paste, delete Funktionen Java Basics - Anfänger-Themen 3
D Über Button abhängig von Auswahl 2 versch. Fenster öffnen Java Basics - Anfänger-Themen 2
onlyxlia Schlüsselworte Was meint man mit "einen Typ" in Java erstellen? Java Basics - Anfänger-Themen 2
S Timer vs ExecutorService: jeden Sonntag um 14.00 Uhr einen Task starten..? Java Basics - Anfänger-Themen 1
P Wieso kann ich als Index für einen Array einen Char angeben? Java Basics - Anfänger-Themen 3
X wie bekomme ich durch Eingabeaufforderung definierte double in einen Befehl, welcher 3 erwartete double braucht? Java Basics - Anfänger-Themen 3
P Gibt es einen anderen Weg um "{}" in IntelliJ zu schreiben? Java Basics - Anfänger-Themen 5
N Java Taschenrechner hat Jemand vlt einen Tipp dafür wie ich jetzt die buttons verbinden kann und das Ergebnis auf dem textfield anzeigen lassen kann Java Basics - Anfänger-Themen 13
F Hat es noch einen Sinn, alte Versionen zu lernen Java Basics - Anfänger-Themen 45
S String Array Buchstaben um einen gewissen Wert verschieben Java Basics - Anfänger-Themen 4
N Kann man einen Iterator nur einmal verwenden Java Basics - Anfänger-Themen 5
M Kommandozeilenparamter als EINEN String werten Java Basics - Anfänger-Themen 5
FireHorses Einen Command erst nach einer Chateingabe aktivieren Java Basics - Anfänger-Themen 1
F Wie kann ich eine Funktion schreiben, die nur in bestimmten Fällen einen Wert zurückgibt? Java Basics - Anfänger-Themen 5
berserkerdq2 Brauche ich while != -1, wenn ich immer einen BufferedReader verwende? Java Basics - Anfänger-Themen 8
berserkerdq2 Habe ein Spiel entwickelt, dass immer in der 4 Runde einen cast-Fehler erhält Java Basics - Anfänger-Themen 3
N Gibt es hierfür einen Shortcut Java Basics - Anfänger-Themen 5
sserio Java Fx, wie erstellt man einen EventHandler, der durch das Drücken eines Button Texte in eine Table view einfügt Java Basics - Anfänger-Themen 17
K Wie verneine ich einen Regex? Java Basics - Anfänger-Themen 2
berserkerdq2 Wie würde man einen regulären Ausdruck in Java schreiben, der prüft, dass zwei bestimtme Zahlen nicht nebeneinadner sind? Java Basics - Anfänger-Themen 3
M Wie kann eine Methode für ein vorhandenes "Array von char" einen Index-Wert zurückliefern? Java Basics - Anfänger-Themen 3
Fats Waller Compiler-Fehler Kann ich einen String und die Summe zweier Char Werte mittels der println Anweisung ausgeben Java Basics - Anfänger-Themen 4
O Ich habe einen String und soll mit matches schauen, ob ein Buchstabe zu einer geraden ANzahl im String vorkommt, wie soll das gehen? Java Basics - Anfänger-Themen 7
O Ich ahbe einen char und diesen soll ich bei .matches prüfen, also ob der char in meiner Zeichenkette vorhanden ist, wie mache ich das? Java Basics - Anfänger-Themen 9
W Unterschiede bei Zugriff auf Objekt und Klassenvariablen über einen Getter? Java Basics - Anfänger-Themen 2
D Einen boolischen Wert aus einer Methode in einer anderen Klasse aufrufen? Java Basics - Anfänger-Themen 11
C Potenzberechnung über switch case. Taschenrechner mit Eingabe über einen grafischen Dialog Java Basics - Anfänger-Themen 22
Poppigescorn Mithilfe einer Arrayliste einen Notenspiegel ausgeben Java Basics - Anfänger-Themen 12
J Eintrag Combobox über einen String auswählen Java Basics - Anfänger-Themen 3
L GUI- wie cancel ich einen Timer? Java Basics - Anfänger-Themen 10
S Aus verschachtelter ArrayList auf einen Wert zugreifen Java Basics - Anfänger-Themen 4
LetsSebi Methode, die einen arry von objekten speichert in einer datei Java Basics - Anfänger-Themen 6
Devin Wo kann man einen Java Lehrplan finden? Java Basics - Anfänger-Themen 5
J Ist es möglich einen int Array wirklich leer zu initialisieren oder zu füllen? Java Basics - Anfänger-Themen 21
P Welche Zeile in Tadople gibt einen compiler error? Java Basics - Anfänger-Themen 5
S First Time Mave: Wie ergänze ich einen Source-Folder? Java Basics - Anfänger-Themen 10
M Pfadprobleme - Zugriff auf einen Ordner im Workspace Java Basics - Anfänger-Themen 17
J Eine Position im String durch einen Integer - Wert teilen Java Basics - Anfänger-Themen 5
P Methode die eigentlich einen Scanner benötigt mit toString() Java Basics - Anfänger-Themen 5
S Erste Schritte Button einen Wert zuweisen & diesen ausgeben Java Basics - Anfänger-Themen 2
M Auf einen Array innerhalb eines Objekts zugreifen Java Basics - Anfänger-Themen 5
V_Fynn03 Erste Schritte Einen Wert in ein TextField einfügen aus einer anderen Klasse Java Basics - Anfänger-Themen 3
J Hat jemand einen Lösungsansatz für diese Aufgabe? Java Basics - Anfänger-Themen 1
F Hilfe für einen Anfänger! Java Basics - Anfänger-Themen 4
O Ziehen im Array um einen Schritt in eine einzige beliebige Richtung Java Basics - Anfänger-Themen 5
N Wie kann ich einen String wieder zusammensetzen und ausgeben lassen? Java Basics - Anfänger-Themen 9
T Fehlermeldung beim Versuch, einen String einzulesen Java Basics - Anfänger-Themen 4
J Wie kann ich z.B. einem int-Wert einen String-Wert zuweisen? Java Basics - Anfänger-Themen 2
steven789hjk543 Kann man mit Java und Eclipse einen Virus programmieren? Java Basics - Anfänger-Themen 13
D Eingabe einscannen, ohne vorher einen Datentypen anzugeben? Java Basics - Anfänger-Themen 1
T Einen Stern malen Java Basics - Anfänger-Themen 32
T Einen Stern malen Java Basics - Anfänger-Themen 2
L Files verschieben in einen Ordner Java Basics - Anfänger-Themen 87
A Mit JComboBox Ergebnis einen Integer aus einer anderen Klasse aufrufen. Java Basics - Anfänger-Themen 2
J Mit for Schleife einen String Rückwärts befüllen Java Basics - Anfänger-Themen 9
J Einen Buttonklick in Label anzeigen Java Basics - Anfänger-Themen 6
S Gibt es einen guten kostenlosen Online-kurs Java Basics - Anfänger-Themen 2
W Wie programmiere ich einen Potenzrechner? Java Basics - Anfänger-Themen 5
B ArrayList besitzt einen Wert zu wenig Java Basics - Anfänger-Themen 16
B Prüfen, ob es schon einen Termin gibt in einem Zeitraum Java Basics - Anfänger-Themen 5
B Wie instanzisiert man einen Cursor richtig? Java Basics - Anfänger-Themen 3
S Interface (WindowBuilder) Panels in einen Frame einfügen Java Basics - Anfänger-Themen 10
J Aufruf einer Methode über einen String Java Basics - Anfänger-Themen 11
C Wie erstellt man einen Timer/Delay? Java Basics - Anfänger-Themen 1
C Wie kann ich einen User Input mit einer If-Anweisung verbinden? Java Basics - Anfänger-Themen 5
J Guten tag, Ich hoffe ihr habt einen schönen Sonntag und könnt mir helfen Java Basics - Anfänger-Themen 2
D Methoden 2 TextWatcher auf einen EditText Java Basics - Anfänger-Themen 4
I Datentypen input.nextCharAt(0) wirft einen Fehler Java Basics - Anfänger-Themen 3
C In einer Methode einen Array zurückgeben Java Basics - Anfänger-Themen 2
S Bestehendes Java Programm, einen festen Wert ändern Java Basics - Anfänger-Themen 17
F Variablen If else: Einer Variable einen Wert hinzufügen oder so? Java Basics - Anfänger-Themen 6
R Übergeben eines Array Strings an einen Spinner Java Basics - Anfänger-Themen 4
Bluedaishi Einen Betrag X auf X Tage verteilen Java Basics - Anfänger-Themen 14
D Einen Wert unter einen ActionListener weitergeben Java Basics - Anfänger-Themen 1
J In Java einen Ton erzeugen Java Basics - Anfänger-Themen 8
C Variablen von einem JFrame in einen anderen übertragen Java Basics - Anfänger-Themen 3

Ähnliche Java Themen

Neue Themen


Oben