rekursion:start
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung | ||
rekursion:start [2024/09/11 14:27] – [Aufgabe 3: Die Türme von Hanoi] Martin Pabst | rekursion:start [Unbekanntes Datum] (aktuell) – gelöscht - Externe Bearbeitung (Unbekanntes Datum) 127.0.0.1 | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
- | ====== 1. Rekursion (Einführung) ====== | ||
- | |||
- | ===== Beispiel 1: Berechnung von Fakultäten ===== | ||
- | <WRAP center round info 60%> | ||
- | Erinnern Sie sich noch an die Fakultätsfunktion? | ||
- | $$0! = 1$$ und | ||
- | $$n! = 1\cdot 2\cdot 3\cdot \ldots \cdot (n-1)\cdot n \ \mathrm{für}\ n \in \mathbb{N} \backslash \{0\},$$ | ||
- | also beispielsweise: | ||
- | $$5! = 1\cdot 2\cdot 3\cdot 4 \cdot 5 = 120$$ | ||
- | \\ | ||
- | * Probieren Sie das folgende Programm aus, auch im Einzelschrittmodus. | ||
- | * Analysieren Sie das Programm genau und überlegen Sie, welche Anweisungen der Reihe nach ausgeführt werden. | ||
- | </ | ||
- | |||
- | < | ||
- | |||
- | <div class=" | ||
- | |||
- | <script type=" | ||
- | Matheklasse m = new Matheklasse(); | ||
- | |||
- | println(m.fakultät(4)); | ||
- | |||
- | class Matheklasse { | ||
- | |||
- | int fakultät(int n) { | ||
- | if(n == 0) { | ||
- | | ||
- | } | ||
- | |||
- | int ergebnis = n * fakultät(n - 1); | ||
- | |||
- | return ergebnis; | ||
- | } | ||
- | |||
- | } | ||
- | </ | ||
- | </ | ||
- | </ | ||
- | |||
- | <WRAP center round info 60%> | ||
- | **Definition: | ||
- | Von **Rekursion** spricht man, wenn sich eine Methode entweder direkt selbst aufruft oder über eine Aufrufkette (z.B. Methode a ruft Methode b auf, die ruft Methode c auf, diese wiederum ruft Methode a auf). \\ \\ | ||
- | |||
- | **Wichtig: | ||
- | * Jede Rekursion benötigt eine **Abbruchbedingung**, | ||
- | * Ruft sich die rekursive Methode genau ein Mal auf, so spricht man von **linearer Rekursion**. Ruft sie sich mehrmals auf, so spricht man von **verzweigter Rekursion** (siehe Aufgabe 1 unten). | ||
- | </ | ||
- | |||
- | |||
- | === Erklärung des Programmablaufs: | ||
- | <WRAP center round info 60%> | ||
- | Um zu verstehen, wieso ein rekursiver Aufruf einer Methode überhaupt funktionieren kann stellen Sie sich am besten vor, dass der Computer bei jedem Aufruf der Methode '' | ||
- | |||
- | </ | ||
- | |||
- | {{ : | ||
- | Hier etwas gröber dargestellt: | ||
- | {{ : | ||
- | |||
- | ===== Aufgabe 1: Die Fibonacci-Folge ===== | ||
- | |||
- | <WRAP center round info 60%> | ||
- | Die [[https:// | ||
- | $$ f_0 = 1 $$ | ||
- | $$ f_1 = 1 $$ | ||
- | $$ f_n = f_{n-2} + f_{n-1}\ \ \mathrm{für}\ \ n > 1 $$ | ||
- | Jedes Folgenglied ist also die Summe der beiden vorhergehenden Folgenglieder. Hier die ersten Glieder: | ||
- | $$1,\ 1,\ 2,\ 3,\ 5,\ 8,\ 13,\ 21,\ 34,\ 55,\ \ldots$$ | ||
- | </ | ||
- | |||
- | <WRAP center round todo 60%> | ||
- | * Programmieren Sie eine Methode, die das n-te Glied der Fibonacci-Folge berechnet. Nutzen Sie dazu rekursive Methodenaufrufe und orientiere Dich am vorherigen Programm (Fakultätsberechnung). | ||
- | * Welchen wesentlichen Unterschied zum vorherigen Programm bemerken Sie? Wie wirkt er sich auf die obigen Diagramme zur Erklärung aus? | ||
- | </ | ||
- | |||
- | [[.fibonacci: | ||
- | |||
- | ===== Beispiel 2: Die Kochkurve ===== | ||
- | <WRAP center round info 60%> | ||
- | Die **Kochkurve** und die aus ihr gewonnene Kochsche Schneeflocke werden [[https:// | ||
- | {{ : | ||
- | Die **Kochsche Schneeflocke** erhält man, wenn man von einem gleichseitigen Dreieck ausgehend dieselbe Iterationsvorschrift immer wieder anwendet. | ||
- | </ | ||
- | |||
- | |||
- | < | ||
- | |||
- | <div class=" | ||
- | |||
- | <script type=" | ||
- | new World(800, 800); | ||
- | new Kochkurve(4); | ||
- | |||
- | class Kochkurve extends Turtle { | ||
- | |||
- | | ||
- | super(100, 600); | ||
- | setBorderWidth(1); | ||
- | | ||
- | // Zeichne das gleichseitige Dreieck: | ||
- | vorwärts(600, | ||
- | turn(120); | ||
- | vorwärts(600, | ||
- | turn(120); | ||
- | vorwärts(600, | ||
- | turn(120); | ||
- | } | ||
- | |||
- | void vorwärts(double länge, int tiefe) { | ||
- | if(tiefe == 0) { | ||
- | | ||
- | } else { | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | } | ||
- | } | ||
- | |||
- | } | ||
- | </ | ||
- | </ | ||
- | </ | ||
- | |||
- | ===== Aufgabe 2: Fraktaler Baum ===== | ||
- | <WRAP center round todo 80%> | ||
- | Erstelle mit Hilfe rekursiver Methodenaufrufe ein Programm, das einen fraktalen Baum zeichnet. Hier die Zeichnung nach der 12. Iteration: \\ | ||
- | {{ : | ||
- | \\ | ||
- | Die Zeichnung beginnt mit einer vertikalen Linie und folgt folgender Iterationsvorschrift: | ||
- | {{ : | ||
- | \\ | ||
- | **Tipp:** \\ | ||
- | Mit der Methode '' | ||
- | |||
- | </ | ||
- | [[.fraktalerBaum: | ||
- | |||
- | <WRAP center round tip 60%> | ||
- | **Für Interessierte: | ||
- | Neben der Kochkurve und fraktalen Bäumen gibt es viele weitere schöne [[https:// | ||
- | * [[https:// | ||
- | * [[https:// | ||
- | * usw. | ||
- | |||
- | Lassen Sie sich herausfordern! | ||
- | |||
- | </ | ||
- | |||
- | ===== Aufgabe 3: Die Türme von Hanoi ===== | ||
- | Das Problem der Türme von Hanoi wird in diesem Video gut erklärt: | ||
- | {{ youtube> | ||
- | **Kurzgefasst: | ||
- | Vor Ihnen befinden sich drei Stäbe (" | ||
- | * Bei jedem Schritt darf nur eine Scheibe bewegt werden. | ||
- | * Es darf **nie** zu einer Situation kommen, bei der auf einem der drei Stäbe eine größere Scheibe oberhalb einer kleinen zu liegen kommt. | ||
- | \\ \\ | ||
- | <WRAP center round todo 60%> | ||
- | **Aufgabe 3: Die Türme von Hanoi** \\ | ||
- | Die drei Türme bekommen die Nummern 1, 2 und 3. \\ \\ Schreibe eine Klasse '' | ||
- | Die Ausgabe von '' | ||
- | < | ||
- | Bewege eine Scheibe von Turm 1 zu Turm 2 | ||
- | Bewege eine Scheibe von Turm 1 zu Turm 3 | ||
- | Bewege eine Scheibe von Turm 2 zu Turm 3 | ||
- | Bewege eine Scheibe von Turm 1 zu Turm 2 | ||
- | Bewege eine Scheibe von Turm 3 zu Turm 1 | ||
- | Bewege eine Scheibe von Turm 3 zu Turm 2 | ||
- | Bewege eine Scheibe von Turm 1 zu Turm 2 | ||
- | Bewege eine Scheibe von Turm 1 zu Turm 3 | ||
- | Bewege eine Scheibe von Turm 2 zu Turm 3 | ||
- | Bewege eine Scheibe von Turm 2 zu Turm 1 | ||
- | Bewege eine Scheibe von Turm 3 zu Turm 1 | ||
- | Bewege eine Scheibe von Turm 2 zu Turm 3 | ||
- | Bewege eine Scheibe von Turm 1 zu Turm 2 | ||
- | Bewege eine Scheibe von Turm 1 zu Turm 3 | ||
- | Bewege eine Scheibe von Turm 2 zu Turm 3 | ||
- | </ | ||
- | </ | ||
- | |||
- | <WRAP center round tip 60%> | ||
- | **Lösungsidee/ | ||
- | * Bei gegebenen Türmen '' | ||
- | * Um '' | ||
- | </ | ||
- | |||
- | [[.hanoi: | ||
- | |||
- | |||
- | <WRAP center round tip 60%> | ||
- | **Für Interessierte: | ||
- | Stellen Sie sich ein Array mit '' | ||
- | [[.quicksort: | ||
- | </ | ||
- | |||
- | |||
- | ===== Aufgabe 4: Floodfill ===== | ||
- | <WRAP center round info 60%> | ||
- | Gegeben ist eine Pixelgrafik mit einem beliebig geformten, zusammenhängenden Gebiet von Pixeln einer Farbe. Gesucht ist ein Algorithmus, | ||
- | Ein Algorithmus, | ||
- | |||
- | |||
- | </ | ||
- | |||
rekursion/start.1726064833.txt.gz · Zuletzt geändert: 2024/09/22 04:37 (Externe Bearbeitung)