programmierkurs javaue 16 rekursiondietrich bolesseite 1 programmierkurs java dr. dietrich boles...
TRANSCRIPT
![Page 1: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/1.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 1
Programmierkurs Java
Dr. Dietrich Boles
Teil
Imperative Programmierung
Unterrichtseinheit 16
Rekursion
![Page 2: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/2.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 2
Gliederung
Rekursion
Definitionen
Rekursive Prozeduren
Rekursive Funktionen
Lokale Variablen
Parameter
Endlosrekursion
Anmerkungen
Beispiele
Backtracking
Zusammenfassung
![Page 3: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/3.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 3
Rekursion (1)
"Definition eines Problems, einer Funktion oder eines Verfahrens durch sich selbst" bereits bekannt:
direkt rekursive Syntaxdiagramme/EBNF:
indirekt rekursive Syntaxdiagramme/EBNF:
Mathematik:
<boolescher Ausdruck> :: "true" | "false" |
"(" <boolscher Ausdruck> ")" ;
<Anweisung> ::= ... | <while-Anweisung> ;
<while-Anweisung> ::= "while" "(" <bA> ")" <Anweisung> ;
n! = 1 falls n = 0
n * (n-1)! sonst{
![Page 4: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/4.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 4
Rekursion (2)
Spielzeug:
MatroschkaQuelle: German Wikipedia
![Page 5: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/5.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 5
Rekursion (3)
Kunst:
M.C. Escher; Bildgalerie
![Page 6: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/6.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 6
Rekursion (4)
Fraktale:
Quelle: German Wikipedia
Pythagoras-Baum
![Page 7: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/7.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 7
Rekursion (5)
Fraktale:
Mandelbrotmenge
http://www.mathematik.ch/anwendungenmath/fractal/julia/MandelbrotApplet.php
Quelle: German Wikipedia, Wolfgag Beyer
![Page 8: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/8.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 8
Definitionen (1)
Definition (Rekursion):
Eine Funktion heißt rekursiv, wenn sie während ihrer Abarbeitung erneut aufgerufen wird.
Definition (direkte Rekursion):
Eine Funktion heißt direkt rekursiv, wenn der erneute Aufruf im Funktionsrumpf der Funktion erfolgt.
Definition (indirekte Rekursion):
Eine Funktion heißt indirekt rekursiv, wenn der erneute Aufruf nicht im Funktionsrumpf der Funktion selbst sondern in einer anderen Funktion erfolgt.
![Page 9: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/9.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 9
Definitionen (2)
Definition (Funktionsinkarnation):
konkreter Aufruf einer Funktion
Definition (Rekursionstiefe):
Anzahl der aktuellen Inkarnationen einer Funktion minus 1
Definition (Variableninkarnation):
konkrete Ausprägung (Speicherplatz) einer Variablen
Iterativer Algorithmus:
Algorithmus, der Wiederholungsanweisungen verwendet
Rekursiver Algorithmus:
Algorithmus, der rekursive Funktionen verwendet
![Page 10: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/10.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 10
Rekursive Prozeduren (1)
Der Hamster soll bis zur nächsten Wand laufen!
Iterative Lösung:
Direkt rekursive Lösung:
void zurMauer() { while (vornFrei()) vor();}
void zurMauerR() { if (vornFrei()) { vor(); zurMauerR(); }}
![Page 11: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/11.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 11
Rekursive Prozeduren (2)
Der Hamster soll alle Körner auf dem aktuellen Feld einsammeln!
Iterative Lösung:
Direkt rekursive Lösung:
void sammle() { while (kornDa()) nimm();}
void sammleR() { if (kornDa()) { nimm(); sammleR(); }}
![Page 12: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/12.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 12
Rekursive Prozeduren (3)
Der Hamster soll bis zur nächsten Wand und dann zurück zur Ausgangsposition laufen!
Iterative Lösung:
void hinUndZurueck() { int anzahl = 0; while (vornFrei()) { vor(); anzahl++; }
linksUm(); linksUm();
while (anzahl > 0) { vor(); anzahl--; }}
![Page 13: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/13.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 13
Rekursive Prozeduren (4)
Der Hamster soll bis zur nächsten Wand und dann zurück zur Ausgangsposition laufen!
Direkt rekursive Lösung:
void hinUndZurueckR() { if (vornFrei()) { vor(); hinUndZurueckR(); vor(); } else { kehrt(); }}
void kehrt() { linksUm(); linksUm();}
![Page 14: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/14.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 14
Rekursive Prozeduren (5)
Schema:
main: hUZR (1.) hUZR (2.) hUZR (3.)
hUZR(); vornFrei -> t vor(); hUZR(); -----> vornFrei -> t vor(); hUZR(); -----> vornFrei -> f kehrt(); <----- vor(); <----- vor(); <-----
Befehlsfolge: vor(); vor(); kehrt(); vor(); vor();
![Page 15: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/15.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 15
Rekursive Prozeduren (6)
Der Hamster soll bis zur nächsten Wand und dann zurück zur Ausgangsposition laufen!
Indirekt rekursive Lösung:
void hinUndZurueckR() { if (vornFrei()) { laufe(); } else { linksUm(); linksUm(); }}
void laufe() { vor(); hinUndZurueckR(); vor();}
![Page 16: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/16.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 16
Rekursive Funktionen (1)
Der Hamster soll die Anzahl an Schritten bis zur nächsten Mauer zählen!
Iterative Lösung:
Rekursive Lösung:
int anzahlSchritteR() { if (vornFrei()) { vor(); return anzahlSchritteR() + 1; } else return 0;}
int anzahlSchritte() { int anzahl = 0; while (vornFrei()) { vor(); anzahl++; } return anzahl;}
![Page 17: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/17.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 17
Rekursive Funktionen (2)
Schema:
main: aSR (1.) aSR (2.) aSR (3.)
i=aSR(); vornFrei -> t vor(); aSR() -----> vornFrei -> t vor(); aSR() -----> vornFrei -> f return 0; 0 <----- return 0 + 1; 1 <----- return 1 + 1; 2 <-----i=2;
![Page 18: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/18.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 18
Lokale Variablen
Der Hamster soll die Anzahl an Körnern im Maul zählen!
int anzahlKoernerR() { if (!maulLeer()) { int anz = 0; gib(); anz = anzahlKoernerR(); nimm(); // Vermeidung von Seiteneffekten! return anz + 1; } else return 0;}
Speicher
aKR
mainmain
anz aKR
main
anz aKR
main
anz
aKR anz aKR anz
aKR anz
...
![Page 19: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/19.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 19
Parameter
Der Hamster soll "anz"-Schritte nach vorne gehen!
void vorR(int anz) { if ((anz > 0) && vornFrei()) { vor(); vorR(anz-1); }}
Speicher
vorR
mainmain
anz=2 vorR
main
anz=2 vorR
main
anz=2
vorR anz=1 vorR anz=1
vorR anz=0
...
![Page 20: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/20.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 20
Endlosrekursion
Endlosrekursion:
Rekursionstiefe: im Prinzip "unendlich"!
erzeugt im allgemeinen einen Laufzeitfehler: Stack overflow!
Dem Java-Interpreter kann man die gewünschte Stackgröße mitteilen!
void sammleR() { if (kornDa()) { sammleR(); nimm(); }}
![Page 21: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/21.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 21
Anmerkungen
Satz: zu jedem rekursiv formulierten Algorithmus gibt es einen
äquivalenten iterativen Algorithmus
Vorteile rekursiver Algorithmen: kürzere Formulierung leichter verständliche Lösung Einsparung von Variablen teilweise sehr effiziente Problemlösungen (z.B. Quicksort)
Nachteile rekursiver Algorithmen: weniger effizientes Laufzeitverhalten (Overhead beim
Funktionsaufruf) Verständnisprobleme bei Programmieranfängern Konstruktion rekursiver Algorithmen "gewöhnungsbedürftig"
![Page 22: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/22.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 22
Beispiel 1
Anzahl an Ziffern einer Zahl ermitteln:
static int length(int zahl) { // iterativ
if (zahl == 0) return 1;
int laenge = 0;
while (zahl != 0) {
zahl /= 10;
laenge++;
}
return laenge;
}
static int lengthR(int zahl) { // rekursiv
if (zahl >= -9 && zahl <= 9) return 1;
return lengthR(zahl/10) + 1;
}
![Page 23: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/23.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 23
Beispiel 2
Berechnung der Fakultätsfunktion:
static int fak(int n) { if (n <= 0) return 1; else return n * fak(n-1);}
n! = 1 falls n = 0
n * (n-1)! sonst{
fak(3) = 3 * fak(2) 2 * fak(1)
1 * fak(0)
1
1 * 1
2 * 1 3 * 2
6
![Page 24: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/24.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 24
Beispiel 3
Berechnung einer Fibonacci-Zahl:
static int fib(int n) { if (n <= 2) return 1; else return fib(n-1) + fib(n-2);}
1 falls n = 1
fib(n) = 1 falls n = 2
fib(n-1) + fib(n-2) sonst{
![Page 25: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/25.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 25
Beispiel 4Türme von Hanoi:
class Hanoi { public static void main(String[] args) { int hoehe = IO.readInt("Hoehe: "); verlegeTurm(hoehe, 1, 3, 2); } static void verlegeTurm(int hoehe, int von, int nach, int ueber) { if (hoehe > 0) { verlegeTurm(hoehe-1, von, ueber, nach); IO.println(von + "-" + nach); verlegeTurm(hoehe-1, ueber, nach, von);} } }
Gegeben: 3 Pfosten mit n ScheibenZiel: Lege alle n Scheiben von 1 nach 3Restriktion 1: immer nur eine Scheibe bewegenRestriktion 2: niemals größere auf kleinere Scheibe 1 2 3
http://thinks.com/java/hanoi/hanoi.htm
Demo
![Page 26: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/26.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 26
Backtracking-Verfahren (1)
Prinzip: Versuch, eine Teillösung eines gegebenen Problems systematisch zu einer
Gesamtlösung auszubauen falls in einer gewissen Situation ein weiterer Ausbau einer vorliegenden
Teillösung nicht mehr möglich ist ("Sackgasse"), werden eine oder mehrere der letzten Teilschritte rückgängig gemacht
die dann erhaltene reduzierte Teillösung versucht man auf einem anderen Weg wieder auszubauen
Wiederholung des Verfahrens, bis Lösung gefunden wird oder man erkennt, dass keine Lösung existiert
Grundlage der Programmiersprache PROLOG! Bekannte Probleme:
Springerproblem Acht-Damenproblem Labyrinthsuche
![Page 27: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/27.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 27
Backtracking-Verfahren (2)
Aufgabe: Der Hamster steht am Eingang eines zyklenfreien Labyrinths, in dem er ein Korn finden und auf dem schnellsten Weg zurücktransportieren soll!
Demo
![Page 28: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/28.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 28
Backtracking-Verfahren (3)
void main() { durchsucheLabyrinth();}
boolean durchsucheLabyrinth() { if (kornDa()) { nimm(); kehrt(); // mach dich auf den Heimweg return true; }
if (linksFrei() && durchsucheTeilLabyrinthLinks()) { kehrt(); // mach dich auf den Heimweg return true; }
if (rechtsFrei() && durchsucheTeilLabyrinthRechts()) { kehrt(); // mach dich auf den Heimweg return true; }
![Page 29: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/29.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 29
Backtracking-Verfahren (4)
if (!vornFrei()) { kehrt(); // Sackgasse return false; }
return durchsucheTeilLabyrinthVorne();} boolean durchsucheTeilLabyrinthLinks() { linksUm(); vor(); boolean gefunden = durchsucheLabyrinth(); // Ausgangsposition einnehmen vor(); linksUm(); return gefunden;}
![Page 30: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/30.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 30
Backtracking-Verfahren (5)
boolean durchsucheTeilLabyrinthRechts() { rechtsUm(); vor(); boolean gefunden = durchsucheLabyrinth(); // Ausgangsposition einnehmen vor(); rechtsUm(); return gefunden;}
boolean durchsucheTeilLabyrinthVorne() { vor(); boolean gefunden = durchsucheLabyrinth(); vor(); // Seiteneffekt: Hamster schaut in andere Richtung return gefunden;}
// + Hilfsfunktionen
![Page 31: Programmierkurs JavaUE 16 RekursionDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit 16 Rekursion](https://reader033.vdocuments.net/reader033/viewer/2022052618/55204d6349795902118b917c/html5/thumbnails/31.jpg)
Programmierkurs Java UE 16 Rekursion Dietrich Boles Seite 31
Zusammenfassung
Rekursive Funktionen: Funktionen, die während ihrer Abarbeitung
erneut aufgerufen werden
Backtracking-Verfahren: Problemlösungsverfahren, das rekursiv
Teilwege durchforstet, um eine Lösung zu finden