Rekursionen Erstellt von J. Rudolf im November 2001 j.rudolf@web.de / www.rudolf-web.de
Themengebiete Was ist eine Rekursion? Lineare Rekursion: Beispiel Struktur einer lin. Rekursion Übung Lösung zu einer Übung
1. Was ist eine Rekursion? Eine Funktion kann nicht nur eine andere Funktion aufrufen sondern auch sich selbst. Dabei wird eine Abbruchbedingung benötigt (um einen Endlos-Aufruf zu verhindern, bei dem der “Stack” überläuft und zu einer Fehlermeldung führt) ist ein sehr komfortables Programmierkonzept!!!!! Bei einer lineare Rekursion: einfacher Selbstaufruf Es gibt auch zwei oder mehrfachen Selbstaufruf
2. Lin. Rekursion: Beispiel Rekursive Definition der Fakultätsfunktion n! = n * (n-1)! und 1!=1 function fac(n:integer):integer; Begin If n=1 Then result:=1 else result:= n*fac(n-1); end; Mit dem Aufruf fac(3) wird so gerechnet: fac(3)=3 * fac(2) -> 2 * fac(1) -> 1 fac(3) ruft fac(2) auf, dieses fac(1) Nun Abbruch (da n=1): also fac(1)=1 Nun wird alles “rückwärts” multipliziert: fac(3) = 3 * 2 * 1 = 6
3. Struktur einer lin. Rekursion Procedure rekursiv; Begin If <Abbruch> Then <Anweisung1> //Rekursionsanfang Else Begin <Anweisung2>; //während des Abstiegs rekursiv; //Selbstaufruf <Anweisung3>; //während des Aufstiegs End;{else} End;{Procedure}
4. Übungen Rekursive Berechnung der Summe der ersten n ungeraden Zahlen ( 1 + 3 + ... + (2n-1) ) Ein “wort” soll umgedreht werden: “trow”. Eine Zeichenfolge soll als Palindrom (z.B. “anna”) erkannt werden. In einen Kreis soll ein um dr=5 kleinerer Kreis gezeichnet werden.
5. Lösung zu Übung (b) Procedure wort(Var str:String); Var hilf1,hilf2:string; Begin If length(str)<2 Then // Abbruchbedingung Else begin hilf1:=copy(str,1,1);hilf2:=copy(str,length(str),1); str:=copy(str,2,length(str)-2); wort(str); str:=hilf2+str+hilf1; End;{if} End;{Dreieck} procedure TForm1.Button1Click(Sender: TObject); Var drehen:String; begin drehen:=Edit1.text; wort(drehen); edit1.text:=drehen; end;
5. Lösung zu Übung (d) In Kreis je einen um dr=5 kleineren Kreis zeichnen: Procedure zeichnekreis(x,y,r:Integer); Begin If r >=10 Then begin // Abbruchbedingungen image1.canvas.circle(x,y,r); // Kreis zeichnen zeichnekreis(x,y,r-5); // Selbstaufruf end;{if} End;{Procedure} Nun kann z.B. bei einer ButtonClick-Prozedur zeichnekreis(150,150,100); aufgerufen werden.
6.) Baumrekursion Spiel: Türme von Hanoi Probiere dieses Spiel zuerst selbst (z. B. im Internet als Applet) mit 2, dann mit 3, dann ... Steinen Sierpinski-Dreieck Kochkurve Wo steckt jeweils die Rekursion?
7. Beispiel zur Baumrekursion Procedure Turm mit Parameter N: Anzahl der Steine A: Ziehe von Turm Nr. .. B: nach Turm Nr. Turm(1,1,2): Ziehe 1 Stein: 1 -> 2 Abbruchbedingung: N=1 Dann: Zug ausführen bzw. Zug notieren Dreifacher Selbstaufruf
Lösung zu „Hanoi“ Procedure Turm(N:Integer; p1,p2,p3:Char); {N: Höhe des Turmes; p1-p3: Werte a,b,c: p1: von z. B. a / p2: nach z. B. c / p3: b ist frei, das „Parkfeld“} Begin If n = 1 //Abbruchbedingung Then listbox1.items.add(`von `+p1+`nach `p2);//oder zeichnen! Else begin Turm(n-1,p1,p3,p2);//bis auf 1 auf dem freien Feld „parken“ Turm(1,p1,p2,p3);//den untersten auf das Zielfeld Turm(n-1,p3,p2,p1);//den Rest vom „Parkfeld“ ins Ziel bringen End;{if} End;{Turm}
Lösung zu „Sierpinski“ Procedure Dreieck(Ax,Ay,Bx,By,Cx,Cy:Integer); {Koordinaten der drei Eckpunkte: A unten links, B unten rechts ...} Begin If sqrt(Bx-Ax)+sqrt(By-Ay) < 2 //Abbruchbedingung: Breite <2 Then form1.image1.Canvas.Polygon([Point(Ax, Ay), Point(Bx, By), Point(Cx,Cy)]) //Dreieck zeichnen Else begin Dreieck(Ax,Ay,(Ax+Bx) div 2, (Ay+By) div 2, (Ax+Cx) div 2, (Ay+Cy) div 2); //Links unten Dreieck((Ax+Bx) div 2, (Ay+By) div 2, Bx,By,(Bx+Cx) div 2, (By+Cy) div 2); //rechts unten Dreieck((Ax+Cx) div 2, (Ay+Cy) div 2, (Bx+Cx) div 2, (By+Cy) div 2,Cx,Cy); //oben End;{if} End;{Dreieck}
Quellenangabe Baumann, Rüdeger: Informatik für die Sekundarstufe 2. Klett