# Binärer Suchbaum



## Keros918 (4. Dez 2020)

Hallo ich bräuchte Hilfe beim schreiben einer objektmethode, die überprüft ob eine Zahl im Binären Suchbaum vorhanden ist.

```
package verkettete_objekte;

public class Knoten {
    public int x;
    public Knoten links;
    public Knoten rechts;
   
    public Knoten(int wert) {
        x = wert;
        links = null;
        rechts = null;
        System.out.println("Ein neuer Knoten mit dem Wert " + x + " wurde erschaffen");
    }

   
    public void einfuegen (int wert) {
        if (wert != x) {
            if (wert < x && links == null) {
                links = new Knoten(wert);
            } else if(wert < x) {
                links.einfuegen(wert);
            }
            if (wert > x && rechts == null) {
                rechts = new Knoten(wert);
            } else if(wert > x){
                rechts.einfuegen(wert);
            }
        } else {
            System.out.println("Der Teilbaum kann nicht erschaffen werden.");
        }
    }
   
    public String toString() {
        String s_links = "";
        String s_rechts = "";
        if (links != null) {
            s_links = links.toString();
        }
        if (rechts != null) {
            s_rechts = rechts.toString();
        }
        String baum = "(" + s_links + x + s_rechts + ")";
        return baum;
    }
   
    public boolean suchen(int suche) {
        boolean enthält = false;
        System.out.println(x);
        if (x == suche) {
            enthält = true;
        }
        if (x < suche) {
            rechts.suchen(suche);
        }
        if (x > suche) {
            links.suchen(suche);
        }
        return enthält;
    }
}
```

Das ist soweit mal das was ich habe und mein Problem ist die Methode "suchen", da sie immer False zurückgibt. Mir ist auch klar warum, nur ist mir nicht klar wie ich das Problem beheben kann.  Ich hoffe hier kann mir jemand helfen.


[CODE lang="java" title="TesterKlasse:"]public class KnotenTester {
    public static void main(String[] args) {
        int neu = 1;
        Knoten wurzel = new Knoten(9);
        wurzel.einfuegen(8);
        wurzel.einfuegen(7);
        wurzel.einfuegen(6);
        wurzel.einfuegen(5);
        wurzel.einfuegen(4);
        wurzel.einfuegen(3);
        wurzel.einfuegen(2);
        wurzel.einfuegen(1);
        System.out.println(wurzel.toString());
        if (wurzel.suchen(neu) == true) {
            System.out.println("Das Element ist enthalten.");
        } else {
            System.out.println("Das Element ist nicht enthalten.");
        }
    }
}[/CODE]


----------



## mihe7 (5. Dez 2020)

Keros918 hat gesagt.:


> Mir ist auch klar warum, nur ist mir nicht klar wie ich das Problem beheben kann. Ich hoffe hier kann mir jemand helfen.


In Deiner suchen-Methode ist `enthält` eine lokale Variable. Für jeden Methodenaufruf gibt es eine eigene lokale Variable `enthält`. Wenn Du also z. B. rechts.suchen() aufrufst und in dem Aufruf true zurückegeben wird, ändert das an der lokalen Variable nichts. Am Ende gibst Du einfach false zurück.


----------



## mihe7 (5. Dez 2020)

Noch zur Verdeutlichung: Du kannst den rekursiven Aufruf bzgl. der lokalen Variable schlicht ignorieren. Der Code verhält sich also wie:

```
public boolean suchen(int suche) {
        boolean enthält = false;
        System.out.println(x);
        if (x == suche) {
            enthält = true;
        }
        if (x < suche) {
            tuIrgendwas();
        }
        if (x > suche) {
            tuIrgendwas();
        }
        return enthält;
    }
```
Wenn x != suche ist, dann ändert sich enthält nicht und dem entsprechend gibst Du false zurück.


----------



## Keros918 (5. Dez 2020)

mihe7 hat gesagt.:


> Noch zur Verdeutlichung: Du kannst den rekursiven Aufruf bzgl. der lokalen Variable schlicht ignorieren. Der Code verhält sich also wie:
> 
> ```
> public boolean suchen(int suche) {
> ...


Danke schonmal, hab das jetzt mit einer statischen Variable versucht und es hat funktioniert.


----------



## Keros918 (5. Dez 2020)

mihe7 hat gesagt.:


> Noch zur Verdeutlichung: Du kannst den rekursiven Aufruf bzgl. der lokalen Variable schlicht ignorieren. Der Code verhält sich also wie:
> 
> ```
> public boolean suchen(int suche) {
> ...


Danke schonmal, hab das jetzt mit einer statischen Variable versucht und es hat funktioniert.


----------



## Keros918 (5. Dez 2020)

Keros918 hat gesagt.:


> Danke schonmal, hab das jetzt mit einer statischen Variable versucht und es hat funktioniert.


Dazu nur eine kurze Frage: Gibt es einen Weg das auch mit einer lokalen Variable zu erledigen? In meiner Aufgabenstellung steht zwar nicht drinnen, dass man das machen muss, aber Interessieren würde mich das schon.


----------



## mihe7 (5. Dez 2020)

Keros918 hat gesagt.:


> hab das jetzt mit einer statischen Variable versucht und es hat funktioniert.


Neiiiiiin: statische Variablen nur für Konstanten verwenden.



Keros918 hat gesagt.:


> Dazu nur eine kurze Frage: Gibt es einen Weg das auch mit einer lokalen Variable zu erledigen?


Natürlich. Du bräuchtest ja nur `enthält` entsprechend zu setzen (überleg mal, wo das sinnvoll gemacht werden kann).


----------



## Keros918 (5. Dez 2020)

mihe7 hat gesagt.:


> Neiiiiiin: statische Variablen nur für Konstanten verwenden.
> 
> 
> Natürlich. Du bräuchtest ja nur `enthält` entsprechend zu setzen (überleg mal, wo das sinnvoll gemacht werden kann).


Ok habs jetzt richtig geschafft.


```
public boolean suchen(int suche) {
        boolean enthält = false;
        if (x == suche) {
            enthält = true;
        }
        if (x < suche && rechts != null) {
            rechts.suchen(suche);
            if (rechts.suchen(suche) == true) {
                    enthält = true;
            }
        }
        if (x > suche && links != null) {
            links.suchen(suche);
            if (links.suchen(suche) == true) {
                    enthält = true;
            }
        }
        return enthält;
    }
}
```

Vielen Dank für die Hilfe


----------



## mihe7 (5. Dez 2020)

Keros918 hat gesagt.:


> Ok habs jetzt richtig geschafft.


Fast. Lösch die Zeilen 8 bis 10 und 14 bis 16 wieder raus und schreib einfach `enthält = rechts.suchen(suche);` (analog unten für links).


----------



## Keros918 (5. Dez 2020)

mihe7 hat gesagt.:


> Fast. Lösch die Zeilen 8 bis 10 und 14 bis 16 wieder raus und schreib einfach `enthält = rechts.suchen(suche);` (analog unten für links).


Das sind jetzt aber nur "kosmetische"  Verbesserungen, wenn ich das richtig sehe oder?


----------



## kneitzel (5. Dez 2020)

Keros918 hat gesagt.:


> Das sind jetzt aber nur "kosmetische"  Verbesserungen, wenn ich das richtig sehe oder?


Nein nicht nur. Bei folgendem Konstrukt:

```
links.suchen(suche);
            if (links.suchen(suche) == true) {
                    enthält = true;
```
Ist die erste Zeile unnötig. Du suchst links aber das Ergebnis interessiert Dich nicht. Daher suchst Du dann innerhalb der if Bedingung gleich erneut.

Was das if mit dem true angeht: Da könnte man von einer kosmetischen Änderung sprechen. Aber im Rahmen von Clean Code wäre es schon besser, da der Code kürzer und auch leichter lesbar wird.


----------



## Keros918 (5. Dez 2020)

kneitzel hat gesagt.:


> Nein nicht nur. Bei folgendem Konstrukt:
> 
> ```
> links.suchen(suche);
> ...


Alles klar, vielen Dank euch nochmal


----------

