Benutzer-Werkzeuge

Webseiten-Werkzeuge


rekursion:start

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
rekursion:start [2024/09/08 13:32] – [Aufgabe 3: Die Türme von Hanoi] Martin Pabstrekursion:start [Unbekanntes Datum] (aktuell) – gelöscht - Externe Bearbeitung (Unbekanntes Datum) 127.0.0.1
Zeile 1: Zeile 1:
-====== 1. Rekursion ====== 
- 
-===== Beispiel 1: Berechnung von Fakultäten ===== 
-<WRAP center round info 60%> 
-Erinnern Sie sich noch an die Fakultätsfunktion? Sie ist so definiert: 
-$$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.  
-</WRAP> 
- 
-<HTML> 
- 
-<div class="java-online" style="height: 450px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'fakultaet1', 'speed': 100000}"> 
- 
-<script type="text/plain" title="Hauptprogramm.java"> 
-Matheklasse m = new Matheklasse(); 
- 
-println(m.fakultät(4)); 
- 
-class Matheklasse { 
-    
-   int fakultät(int n) { 
-      if(n == 0) { 
-         return 1; 
-      } 
- 
-      int ergebnis = n * fakultät(n - 1); 
- 
-      return ergebnis; 
-   } 
- 
-} 
-</script> 
-</div> 
-</HTML> 
- 
-<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**, die das Unterbrechen der Aufrufkette nach endlich vielen Schritten sicherstellt. 
-</WRAP> 
- 
- 
-=== 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 ''fakultät'' die Werte aller Parameter und lokalen Variablen "speichert" und bei jeder Rückkehr wiederherstellt. Bei jedem Betreten der Methode ''fakultät'' erhalten die Parameter und lokalen Variablen daher "neue" Werte. \\ \\  
-TODO <Erklärung des Stacks für Interessierte>  
-</WRAP> 
-  
-{{ :rekursion:rekursion_erklaerung.png?direct&600 |}} 
-Hier etwas gröber dargestellt: 
-{{ :rekursion:rekursion.svg |}} 
- 
-===== Aufgabe 1: Die Fibonacci-Folge ===== 
- 
-<WRAP center round info 60%> 
-Die [[https://en.wikipedia.org/wiki/Fibonacci_sequence|Fibonacci-Folge]] ist wie folgt definiert: 
-$$ f_1 = 1 $$ 
-$$ f_2 = 1 $$ 
-$$ f_n = f_{n-2} + f_{n-1}\ \ \mathrm{für}\ \ n > 2 $$ 
-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> 
- 
-<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? 
-</WRAP> 
- 
-[[.fibonacci:start|Musterlösung -> Bitte erst nach der Informatikstunde ansehen!]] 
- 
-===== Beispiel 2: Die Kochkurve ===== 
-<WRAP center round info 60%> 
-Die **Kochkurve** und die aus ihr gewonnene Kochsche Schneeflocke werden [[https://de.wikipedia.org/wiki/Koch-Kurve|in diesem Wikipedia-Artikel]] schön beschrieben. Die Kochkurve ergibt sich, indem man von einer waagrechten Strecke ausgeht und bei jedem Iterationsschritt jede Strecke folgendermaßen ersetzt: 
-{{ :rekursion:pasted:20240908-142937.png?300 }} 
-Die **Kochsche Schneeflocke** erhält man, wenn man von einem gleichseitigen Dreieck ausgehend dieselbe Iterationsvorschrift immer wieder anwendet. 
-</WRAP> 
- 
- 
-<HTML> 
- 
-<div class="java-online" style="height: 400px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'hanoiloesung', 'speed': 100000}"> 
- 
-<script type="text/plain" title="Hauptprogramm.java"> 
-new World(800, 800); 
-new Kochkurve(4); 
- 
-class Kochkurve extends Turtle { 
-    
-   Kochkurve(int tiefe) { 
-      super(100, 600); 
-      setBorderWidth(1); 
-       
-      // Zeichne das gleichseitige Dreieck: 
-      vorwärts(600, tiefe); 
-      turn(120); 
-      vorwärts(600, tiefe); 
-      turn(120); 
-      vorwärts(600, tiefe); 
-      turn(120); 
-   } 
- 
-   void vorwärts(double länge, int tiefe) { 
-      if(tiefe == 0) { 
-         forward(länge); 
-      } else { 
-         vorwärts(länge / 3, tiefe - 1); 
-         turn(-60); 
-         vorwärts(länge / 3, tiefe - 1); 
-         turn(120); 
-         vorwärts(länge / 3, tiefe - 1); 
-         turn(-60); 
-         vorwärts(länge / 3, tiefe - 1); 
-      } 
-   } 
- 
-} 
-</script> 
-</div> 
-</HTML> 
- 
-====== 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: \\  
-{{ :rekursion:pasted:20240908-150155.png }} 
-\\  
-Die Zeichnung beginnt mit einer vertikalen Linie und folgt folgender Iterationsvorschrift: \\  
-{{ :rekursion:fraktaler_baum.svg?600 |}} 
-\\  
-**Tipp:** \\  
-Mit der Methode ''penUp()'' kannst Du den Stift der Turtle anheben, so dass sie nicht mehr zeichnet. Mit der Methode ''penDown()'' kannst Du ihn wieder herabsenken, so dass die Turtle wieder zeichnet.  
- 
-</WRAP> 
-[[.fraktalerBaum:start3826|Lösung]] 
- 
-<WRAP center round tip 60%> 
-**Für Interessierte:** \\ \\  
-Neben der Kochkurve und fraktalen Bäumen gibt es viele weitere schöne [[https://de.wikipedia.org/wiki/Fraktal|fraktale]] Punktmengen, die mit wenig Aufwand durch einfach rekursive Methoden gezeichnet werden können: 
-  * [[https://de.wikipedia.org/wiki/Drachenkurve|Die Drachenkurve]] 
-  * [[https://de.wikipedia.org/wiki/Hilbert-Kurve|Die Hilbertkurve]] 
-  * usw. 
- 
-Lassen Sie sich herausfordern! 
- 
-</WRAP> 
- 
-===== Aufgabe 3: Die Türme von Hanoi ===== 
-Das Problem der Türme von Hanoi wird in diesem Video gut erklärt: 
-{{ youtube>UMPneeBzQHk?large }} 
-**Kurzgefasst:** \\  
-Vor Ihnen befinden sich drei Stäbe ("Türme"), wobei sich auf dem rechten der drei Stäbe ''n'' der Größe nach geordnete Scheiben befinden, die größte zuunterst. Die Aufgabe besteht darin, alle ''n'' Scheiben zum linken Stab zu bringen, wobei folgende Spielregeln gelten: 
-  * 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 ''Hanoi'' mit einer Methode ''erkläreLösung(int startTurmNummer, int zielTurmNummer, int n)'', die in Textform erklärt, wie man ''n'' Scheiben unter Einhaltung der im Video erklärten Regeln vom Turm ''startTurmNummer'' zum Turm ''zielTurmNummer'' bringt. \\ \\  
-Die Ausgabe von ''erkläreLösung(1, 3, 4)'' soll beispielsweise so aussehen:  
-<code> 
-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 
-</code> 
-</WRAP> 
- 
-<WRAP center round tip 60%> 
-**Lösungsidee/Tipps:** \\ 
-  * Bei gegebenen Türmen ''x'' und ''y'' hat der übrige Turm dann immer die Nummer ''6 - x - y'' 
-  * Um ''n'' Scheiben von Turm x zu Turm y zu bewegen, bewege zuerst ''n - 1'' Scheiben von Turm ''x'' zu Turm ''6 - x - y'', dann eine (die größte!) Scheibe von Turm ''x'' zur Turm ''y'' und dann ''n - 1'' Scheiben von Turm ''6 - x - y'' zu Turm ''y''. Die Methode ''erkläreLösung'' muss sich also nur geeignet selbst aufrufen. 
-</WRAP> 
- 
-[[.hanoi:loesung:start8042|Lösung]]  \\  
- 
- 
-<WRAP center round tip 60%> 
-**Für Interessierte:** Quicksort \\ 
-[[.quicksort:start|Hier ist der Algorithmus erklärt und implementiert.]] 
-</WRAP> 
  
rekursion/start.1725802324.txt.gz · Zuletzt geändert: 2024/09/22 04:37 (Externe Bearbeitung)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki