Verstehe Rekursion nicht ganz

Käsekuchen

Mitglied
Java:
public class Baum {
    private Knoten start;
    
    //Baum erstellen
    public void einfuegen(Knoten neu) {
        if(start == null) {
            start = neu;
        }
        else {
            einfuegen(start,neu);
        }
    }
    public void einfuegen(Knoten temp, Knoten neu) {
        if(neu.getAlter()<temp.getAlter()) {
            if(temp.left==null) temp.left = neu;
            else einfuegen(temp.left,neu);
        }
        if(neu.getAlter()>temp.getAlter()) {
            if(temp.right==null) temp.right = neu;
            else einfuegen(temp.right,neu);
        }
    }
    
    //Baum ausgeben
    public void ausgeben() {
        ausgeben(start);
    }
    
    public void ausgeben(Knoten temp) {
        if(temp == null) return;
        
        if(temp.left!=null) ausgeben(temp.left);
        
        System.out.println(temp.getAlter());
        
        if(temp.right!=null) ausgeben(temp.right);
        
    }
        public static void main(String[]args) {
        Baum xxx = new Baum();
        Knoten eins = new Knoten("Jakob",23);
        Knoten zwei = new Knoten("Jonas",24);
        Knoten drei = new Knoten("Eva",26);
        Knoten vier = new Knoten("Peter",28);
        
        xxx.einfuegen(eins);
        xxx.einfuegen(zwei);
        xxx.einfuegen(drei);
        xxx.einfuegen(vier);
        
        
       
        System.out.println();
        
    }
}
Java:
public class Knoten {
    private String name;
    private int alter;
    
    Knoten left;
    Knoten right;
    
    public Knoten(String name, int alter) {
        this.name=name;
        this.alter=alter;
    }
    
    public String getName() {
        return name;
    }
    public int getAlter() {
        return alter;
    }
}

Ich bräuchte mal eure Hilfe, irgendwie hab ich Rekursion nich so wirklich verstanden. Die Frage bezieht sich auf die ausgeben() Methode. Ich versteh einfach nicht, was da genau passiert. Für mich ist es so weit verständlich, dass wir im Baum immer weiter runter gehen bis eben System.out.println(temp.getAlter()); ausgeführt wird. Aber wie kommt es zustande, dass die anderen werte auch ausgegeben werden ?
 

Blender3D

Top Contributor
Aber wie kommt es zustande, dass die anderen werte auch ausgegeben werden ?
Der Aufruf der Methode ausgeben( Knoten ) wird im Funktion Stack gespeichert.
Start.......=.... 17
......................./.....\
...................12......13
.................../
................15
ausgeben( 17 ) -> ausgeben( 12 ) -> ausgeben ( 15) -> ausgeben(13)
Ausgabe:
15
12
17
13
 

mihe7

Top Contributor
Ich versteh einfach nicht, was da genau passiert.
Tatsächlich passiert da nichts besonderes: es wird eine Methode aufgerufen, das ist alles. Dass es sich dabei um die gleiche Methode handelt, in der man sich gerade befindet, macht erstmal keinen Unterschied.

D. h. Du kannst die Methodenaufrufe zunächst einmal wie eine Black-Box behandeln, wir können sie einfach mal ersetzen:
Java:
    public void ausgeben(Knoten temp) {
        if(temp == null) return;
        
        if(temp.left!=null) x(temp.left);
        
        System.out.println(temp.getAlter());
        
        if(temp.right!=null) x(temp.right);        
    }

Was also passiert nun in der Methode? Wenn temp null ist, wird die Methode sofort beendet. Wenn temp.left != null gilt, wird eine Methode (hier x) aufgerufen, dabei wird temp.left als Argument übergeben. Nun endet der Aufruf von x irgendwann auch wieder und im Anschluss wird das Alter von temp ausgegeben. Danach wird geprüft, ob right != null ist. In dem Fall wird nochmal eine Methode (hier x) aufgerufen, dabei wird temp.right als Argument übergeben. Wenn der Aufruf von x endet, sind wir am Ende der Methode ausgeben angelangt und die Methode endet. Das war es auch schon.

Jetzt kannst Du x wieder durch ausgeben ersetzen und den Spaß genau so nachvollziehen. Wenn Du also den Baum von @Blender3D nimmst, dann kannst Du schon einmal sagen: ok, es wird ausgeben(12) ausfgerufen, danach wird die 17 ausgegeben, danach wird ausgeben(13) aufgerufen.

Code:
ausgeben(12)
17
ausgeben(13)

Was passiert bei ausgeben(12)? Naja, das gleiche wieder: es wird ausgeben(15) aufgerufen, es wird die 12 ausgegeben, danach passiert nichts weiter, da 12 keinen rechten Kindknoten besitzt.

Code:
ausgeben(15)
12
17
ausgeben(13)

Was passiert bei ausgeben(15)? Es gibt weder einen linken noch einen rechten Kindknoten, also wird nur die 15 ausgegeben:
Code:
15
12
17
ausgeben(13)
Bleibt noch ausgeben(13)... Hier gilt das gleiche wie gerade eben: kein linker, kein rechter Kindknoten, nur die 13 wird ausgegeben:
Code:
15
12
17
13
Fertig.
 

White_Fox

Top Contributor
Mal zum allgemeinen Verständnis:

Das Bild in dem Artikel verdeutlicht das eigentlich perfekt, auch wenn es kein Quellcode ist.

Rekursion ist auch eine Problemlösungsstrategie. Komplexe Sachverhalte können oft mit rekursiv formulierten Regeln sehr elegant erfasst werden. Das Grundprinzip ist dabei dann das Zurückführen einer allgemeinen Aufgabe auf eine einfachere Aufgabe derselben Klasse. Das wird u. a. auch beim sogenannten rekursiven Programmieren genutzt: Um Rekursion entstehen zu lassen, muss eine Prozedur, Funktion oder Methode lediglich sich selbst aufrufen. Dieser Prozess läuft weiter, bis eine im Programm enthaltene Abbruchbedingung greift.
 

Käsekuchen

Mitglied
Tatsächlich passiert da nichts besonderes: es wird eine Methode aufgerufen, das ist alles. Dass es sich dabei um die gleiche Methode handelt, in der man sich gerade befindet, macht erstmal keinen Unterschied.

D. h. Du kannst die Methodenaufrufe zunächst einmal wie eine Black-Box behandeln, wir können sie einfach mal ersetzen:
Java:
    public void ausgeben(Knoten temp) {
        if(temp == null) return;
       
        if(temp.left!=null) x(temp.left);
       
        System.out.println(temp.getAlter());
       
        if(temp.right!=null) x(temp.right);       
    }

Was also passiert nun in der Methode? Wenn temp null ist, wird die Methode sofort beendet. Wenn temp.left != null gilt, wird eine Methode (hier x) aufgerufen, dabei wird temp.left als Argument übergeben. Nun endet der Aufruf von x irgendwann auch wieder und im Anschluss wird das Alter von temp ausgegeben. Danach wird geprüft, ob right != null ist. In dem Fall wird nochmal eine Methode (hier x) aufgerufen, dabei wird temp.right als Argument übergeben. Wenn der Aufruf von x endet, sind wir am Ende der Methode ausgeben angelangt und die Methode endet. Das war es auch schon.

Jetzt kannst Du x wieder durch ausgeben ersetzen und den Spaß genau so nachvollziehen. Wenn Du also den Baum von @Blender3D nimmst, dann kannst Du schon einmal sagen: ok, es wird ausgeben(12) ausfgerufen, danach wird die 17 ausgegeben, danach wird ausgeben(13) aufgerufen.

Code:
ausgeben(12)
17
ausgeben(13)

Was passiert bei ausgeben(12)? Naja, das gleiche wieder: es wird ausgeben(15) aufgerufen, es wird die 12 ausgegeben, danach passiert nichts weiter, da 12 keinen rechten Kindknoten besitzt.

Code:
ausgeben(15)
12
17
ausgeben(13)

Was passiert bei ausgeben(15)? Es gibt weder einen linken noch einen rechten Kindknoten, also wird nur die 15 ausgegeben:
Code:
15
12
17
ausgeben(13)
Bleibt noch ausgeben(13)... Hier gilt das gleiche wie gerade eben: kein linker, kein rechter Kindknoten, nur die 13 wird ausgegeben:
Code:
15
12
17
13
Fertig.
Ich versteh irgendwie nur, wie es zur ersten Ausgabe kommt. Wenn ich bei System.out.println(temp.getAlter()); bin, dann wird mir das Alter ausgegeben. Dann ist die Methode doch vorbei. Warum werden aber alle Zahlen ausgegeben und nicht nur eine
 

Jw456

Top Contributor
Du bist ja den Baum von oben nach unten Links durch gegangen . Und hast mehrere habfertige Methoden auf dem Stack liegen.
Die jetzt nun weiter abgearbeitet werden. Bis wirklich alle Methoden ferig bearbeit wurden.
 

White_Fox

Top Contributor
Mal ein einfacheres Beispiel, vielleicht findest du das Muster in deinem großen Code ja wieder. Nimm mal diese Methode:

Java:
/*
 *Zählt runter bis auf 0
 */
public int countDown(int i){
    if(i >= 0){}
        System.out.println(countDown(i - 1));
    }
    return start;
}

Prinzipiell solltest du diese Methode jetzt einfach mit einem int, z.B. 3, füttern und es die Ausgabe
3
2
1
0
auf dem Bildschirm erscheinen. Gut möglich daß da ein paar Fehlerchen sind wie daß die Null zum Schluß doppelt ausgegeben wird, aber darum geht es erstmal nicht.
Was in der Methode passiert, ist daß sie sich fortwährend selbst aufruft, sofern der Parameter i größer oder gleich null ist, sonst wird einfach der Parameter zurückgegeben. Das ist, was Jw456 mit "halbfertigen Methoden auf dem Stack" meinte, die Methode ruft sich erstmal so oft auf wie benötigt, und dann liefern die vielen Aufrufe ihr jeweiliges Ergebnis zurück. Sieht dann so aus:

rekursion.PNG

In deinem Code fängst du links beim oberen Pfeil an mit einem einzigen Methodenaufruf:
Java:
//Rufe die Methode countDown(i) auf, entspricht dem oberen linken Pfeil im Bild...
countDown(3);
//...und hier bist du schon fertig, d.h. der untere Pfeil auf der linken Seite.

Damit erschlägst du ein Problem in einem Einzeiler, brauchst keine Schleife, keine Zählvariable oder dergleichen, sondern einfach nur ein bischen Platz im Speicher.
 

mihe7

Top Contributor
Wenn ich bei System.out.println(temp.getAlter()); bin, dann wird mir das Alter ausgegeben. Dann ist die Methode doch vorbei.
Du verwechselst Methode und Ausführung der Methode im Rahmen eines Methodenaufrufs. Es endet nicht die Methode, sondern nur die Ausführung eines konkreten Aufrufs. Diese Aufrufe können verschachtelt sein.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
A Hilfe bei Rekursion,Ich verstehe nicht,wie funktioniert die Rekursion in der Methode "walk" Java Basics - Anfänger-Themen 13
nbergmann x /= n : Verstehe ich nicht. Java Basics - Anfänger-Themen 24
S Schulaufgabe - verstehe leider die Aufgabe nicht Java Basics - Anfänger-Themen 4
ZH1896ZH Verstehe verschieden Scanner und hasNext() nicht ganz Java Basics - Anfänger-Themen 2
ZH1896ZH OOP Verstehe nicht was der Hinweis bedeutet, bitte um Hilfe! Java Basics - Anfänger-Themen 2
A Shopping Cart Programm. Verstehe einige Zusammenhänge nicht Java Basics - Anfänger-Themen 1
T Brauche Hilfe um ein Programm zu verstehe Java Basics - Anfänger-Themen 4
K Erste Schritte Ich verstehe das Summenprogramm nicht Java Basics - Anfänger-Themen 10
S Ich verstehe die RegEx Tabelle von Javadoc nicht so ganz Java Basics - Anfänger-Themen 3
V Erste Schritte Array.length[x] in einer Schleife - ich verstehe das nicht Java Basics - Anfänger-Themen 1
Y Erste Schritte Ich verstehe this. nicht so richtig Java Basics - Anfänger-Themen 5
DaCrazyJavaExpert Methoden Verstehe Feheler nicht! Java Basics - Anfänger-Themen 7
Henri ich verstehe gerade nicht die Methode Java Basics - Anfänger-Themen 6
dave253 Ich verstehe folgenden Code nicht.. Java Basics - Anfänger-Themen 12
V Verstehe die Lösung einer Aufgabe von Grunkurs-Java nicht. Java Basics - Anfänger-Themen 11
J Verstehe die NullPointerException nicht Java Basics - Anfänger-Themen 1
J Verstehe meine HashSet Ausgabe nicht Java Basics - Anfänger-Themen 5
P Verstehe Lösung einer Aufgabe von "Grundkurs-Java" nicht Java Basics - Anfänger-Themen 5
O Ich verstehe nicht, was Eclipse von mir will Java Basics - Anfänger-Themen 10
G Methoden Verstehe nicht was in der Methode gemacht wird? Java Basics - Anfänger-Themen 5
M Verstehe das Programm(Quellcode) nicht!! Java Basics - Anfänger-Themen 12
B Verstehe ZufallInt = (int) (Math.random() * 5 + 1); nicht Java Basics - Anfänger-Themen 9
J Rekursiver Horner-Schema-Algorithmus - Verstehe ich ihn richtig? Java Basics - Anfänger-Themen 2
F verstehe diese Variable nicht... Java Basics - Anfänger-Themen 4
A Codezeile die ich nicht verstehe Java Basics - Anfänger-Themen 7
Pentalon Ein Aufruf den ich nicht verstehe Java Basics - Anfänger-Themen 11
V Verstehe die Logik nicht ... Java Basics - Anfänger-Themen 30
C rekursive Methode verstehe nicht! Java Basics - Anfänger-Themen 3
B verstehe methode nicht methode Java Basics - Anfänger-Themen 2
B Erste Schritte Verstehe das nicht Java Basics - Anfänger-Themen 3
C verstehe get und set nicht Java Basics - Anfänger-Themen 3
J Interface Wie funktioniert das mit den Interfaces. Ich verstehe es einfach nicht! :( Java Basics - Anfänger-Themen 15
T ich verstehe array nicht! Java Basics - Anfänger-Themen 11
P for Schleife mit break, verstehe die Ausgabe nicht Java Basics - Anfänger-Themen 6
A Verstehe readLine()-Funktion nicht Java Basics - Anfänger-Themen 3
A Verstehe das GUI nicht! Java Basics - Anfänger-Themen 7
D Verstehe Zusammenhang nicht- Und ihr? Java Basics - Anfänger-Themen 4
M THREADS - Ich verstehe es nicht Java Basics - Anfänger-Themen 10
T Verstehe Bufferreader prinzip nicht Java Basics - Anfänger-Themen 3
E I-JVM verstehe ich das richtig (bytecode aufgabe) Java Basics - Anfänger-Themen 2
M Verstehe Aufgabe nicht, wie kann man schleifen einbauen? Java Basics - Anfänger-Themen 5
N Verstehe Step10 bei jME Eclipsetutorial nicht Java Basics - Anfänger-Themen 4
L Verstehe den Wert nicht! If-Anweisung Java Basics - Anfänger-Themen 5
N Verstehe diese Aufgabe nicht! Java Basics - Anfänger-Themen 16
Rudolf Verstehe das Ergebnis nicht - bitte erklären Java Basics - Anfänger-Themen 7
S Finde den Fehler nicht/ verstehe Anweisung nicht Java Basics - Anfänger-Themen 12
K Ich verstehe switch einfach nicht Java Basics - Anfänger-Themen 4
C Verstehe Code-Teil nicht. Java Basics - Anfänger-Themen 2
S Ich verstehe diese Methode nicht! Java Basics - Anfänger-Themen 6
G Verstehe das nicht. bitte um hilfe Java Basics - Anfänger-Themen 13
R Thread startet nicht, verstehe nicht warum Java Basics - Anfänger-Themen 2
R Verstehe die Ausgabe von folgendem Code nicht Java Basics - Anfänger-Themen 4
A verstehe aufgabenstellung nicht! Java Basics - Anfänger-Themen 47
S verstehe den fehler nicht Java Basics - Anfänger-Themen 14
C Verstehe die Syntax nicht! Java Basics - Anfänger-Themen 2
M Verstehe den Quellcode nicht ganz Java Basics - Anfänger-Themen 3
7 Verstehe Programm nicht Java Basics - Anfänger-Themen 6
G verstehe das problem nicht :( Java Basics - Anfänger-Themen 4
S RegEx Syntax - ich verstehe sie einfach nicht! Java Basics - Anfänger-Themen 3
G verstehe den unterschied zwischen equals und == nicht Java Basics - Anfänger-Themen 3
E Verstehe eine Schleife nicht Java Basics - Anfänger-Themen 5
B Eine Linie zeichnenmit Java, ich verstehe das einfach nicht Java Basics - Anfänger-Themen 4
G Verstehe einen Aufruf absolut nicht Java Basics - Anfänger-Themen 2
P Frage zu Rekursion und Backtracking Java Basics - Anfänger-Themen 2
DiyarcanZeren Rekursion in Java Java Basics - Anfänger-Themen 5
M Variablen Rekursion mit 2 Parameteren Java Basics - Anfänger-Themen 4
sserio Rekursion größten Primfaktor finden funktioniert nicht Java Basics - Anfänger-Themen 8
M Lösungsweg Rekursion Java Basics - Anfänger-Themen 1
C StackOverflow bei Rekursion Java Basics - Anfänger-Themen 7
D Rekursion - Ich raffs nicht Java Basics - Anfänger-Themen 16
N Methoden Rekursion mit Kreisen Java Basics - Anfänger-Themen 7
P9cman Vokale in einem String überprüfen mittels Rekursion Java Basics - Anfänger-Themen 8
J Rekursion Java Basics - Anfänger-Themen 22
T Rekursion Programmierverständnis Java Basics - Anfänger-Themen 12
K Rekursion: Rechenmauer mit Array erstellen Java Basics - Anfänger-Themen 17
K Rekursion einer Zahlenfolge (Ab- und Aufzählung) Java Basics - Anfänger-Themen 6
Zeppi Rekursion Java Basics - Anfänger-Themen 15
V Backtracking und Rekursion Java Basics - Anfänger-Themen 15
L REKURSION Java Basics - Anfänger-Themen 13
Kirby.exe Rekursion Java Basics - Anfänger-Themen 7
N for Schleife durch Rekursion ersetzen Java Basics - Anfänger-Themen 6
X Rekursion Java Basics - Anfänger-Themen 3
H Rekursion Java Basics - Anfänger-Themen 2
D Erste Schritte Rekursion Java Basics - Anfänger-Themen 13
M Rekursion Tage Ansteckung gesamte Bevölkerung Java Basics - Anfänger-Themen 15
M Java Rekursion Java Basics - Anfänger-Themen 9
G Java Rekursion Java Basics - Anfänger-Themen 5
J Rekursion Klausur Aufgabe Java Basics - Anfänger-Themen 2
N Rekursion Java Basics - Anfänger-Themen 18
M Verständnisproblem der Rekursion bei Arrays Java Basics - Anfänger-Themen 8
X Rekursion Rätsel Java Basics - Anfänger-Themen 4
N Klassen Rekursion mit Feldern von Objekten Java Basics - Anfänger-Themen 14
W Rekursion Java Basics - Anfänger-Themen 0
D Konsolenausgabe Zahlenfolge Rekursion Java Basics - Anfänger-Themen 3
J Ping Pong Methode mit Rekursion Java Basics - Anfänger-Themen 1
N Rekursion Java Basics - Anfänger-Themen 1
B Rekursion Basic Java Basics - Anfänger-Themen 15
O Rekursion Mergesort Java Basics - Anfänger-Themen 18
G Rekursion Java Basics - Anfänger-Themen 20
M Rekursion Java Basics - Anfänger-Themen 7

Ähnliche Java Themen

Neue Themen


Oben