Rekursion - bei informatica didactica

Werbung
Michael Fothe, Jena:
(15. März 2004)
Rekursion – ein Thema für den Informatikunterricht
Hätte es im Mittelalter Rechenanlagen gegeben, dann wären
bestimmt einige Programmierer wegen Ketzerei von andersgesinnten Kollegen auf dem Scheiterhaufen verbrannt
worden.
S. GILL (1960)
1 Einführung
In der fachdidaktischen Literatur der letzten zehn Jahre wird das Thema Rekursion
unterschiedlich gewichtet. WAGENKNECHT (1994) befasst sich unter Anwendung
der Programmiersprache Scheme detailliert mit dem Thema. BAUMANN (1996) setzt
sich mit den Möglichkeiten der Rekursion auseinander. RECHENBERG (1997)
betrachtet die Rekursion, weil zu speziell, als in der Schulinformatik eher verzichtbar.
HUBWIESER (2000) geht auf sie nicht näher ein. Bei SCHUBERT&SCHWILL (2004)
ist Rekursion bei der fundamentalen Idee Algorithmisierung aufgeführt (S. 96). Das
Ziel dieser Arbeit ist eine Positionsbestimmung innerhalb dieser Bandbreite. Die
Frage, ob das Thema Rekursion in einen zeitgemäßen Informatikunterricht an
allgemein bildenden Schulen gehört, wird aus zwei Gründen bejaht: Rekursion spielt
in Theorie und Praxis der Informatik eine wesentliche Rolle (vgl. Sprachdefinitionen
von Programmiersprachen, Algorithmen zur Verarbeitung von Listen und
Syntaxanalyse mittels rekursiven Abstiegs) und es ist Aufgabe von Schule, frühzeitig
in wichtige Denk- und Arbeitsweisen einzuführen. Die Frage wird im Resümee noch
einmal aufgegriffen werden. In dieser Arbeit geht es um Unterrichtsziele, Beispiele
und methodisches Herangehen. Dazu werden Erfahrungen, die der Autor im eigenen
Unterricht in den Klassenstufen 9-12 und in der Thüringer Lehrerfortbildung
gewonnen hat, theoretisch systematisierend aufgearbeitet. Nachfolgend wird
Rekursion nicht als etwas Natürliches dargestellt. Nur wenige Beispiele für
Endrekursion werden angegeben. Baumstrukturen und die Äquivalenz von Iteration
und Rekursion werden thematisiert. In diesen Punkten besteht Übereinstimmung mit
RECHENBERG (1997).
2 Zugänge zur Rekursion
In diesem Abschnitt werden
Informatikunterricht skizziert.
sechs
Zugänge
zur
Rekursion
für
den
2.1 Zugang über Sprachbeschreibungen
Die Syntax von Programmiersprachen wird häufig auf rekursive Art angegeben.
Damit wird eine kompakte Beschreibung erreicht. Ein erstes Beispiel ist die
syntaktische Definition von Anweisung in der Programmiersprache Java, die
nachfolgend auszugsweise angegeben ist. Die Definition erfolgt mithilfe der EBNF.
Anweisung = … ( …
| “if“ “(“ Ausdruck “)“ Anweisung [ “else“ Anweisung ]
| “while“ “(“ Ausdruck “)“ Anweisung
| “return“ [ Ausdruck ] “;“
| … ).
Das zu definierende Nichtterminalsymbol Anweisung ist mehrfach auf der rechten
Seite der Definition angegeben, d. h. bei der Definition von Anweisung wird
Anweisung verwendet.
Ein zweites Beispiel ist die Syntax der Ausdrücke in der Programmiersprache
Oberon-2:
Relation = “=“ | “#“ | “< “ | “<= “ | “>“ | “>=“ | “IN“ | “IS“.
AddOperator = “+“ | “-“ | “OR“.
MulOperator = “*“ | “/“ | “DIV“ | “MOD“ | “&“.
Ausdruck = EinfacherAusdruck [ Relation EinfacherAusdruck ].
EinfacherAusdruck = [ “+“ | “-“ ] Term { AddOperator Term }.
Term = Faktor { MulOperator Faktor }.
Faktor = Zahl | ZeichenKonstante | Zeichenkette | NIL | Menge |
Bezeichner [ AktuelleParameter ] | “(“ Ausdruck “)“ | “~“ Faktor.
Der syntaktische Aufbau eines Ausdrucks wird durch ein System von
Nichtterminalsymbolen rekursiv beschrieben (Ausdruck, EinfacherAusdruck, Term
und Faktor). Ein Faktor kann z. B. eine Zahl, ein Variablenbezeichner oder – und
damit wird die Rekursion deutlich – wieder ein Ausdruck (eingeschlossen in runde
Klammern) sein. Nach der Beschreibung stellen z. B. die Zeichenfolgen 2*a+b=c,
1.0-(x-1.0)/(y-1.0) und a+b*(c+d*(e+f*(g+h*i))) syntaktisch korrekte Ausdrücke dar.
Die Schülerinnen und Schüler sollen in der Lage sein, aus den
Sprachbeschreibungen syntaktisch korrekte Zeichenfolgen zu bilden und die
Korrektheit einer gegebenen Zeichenfolge zu überprüfen. Ein drittes Beispiel ist die
„Sprache der Bäume“, bei der mithilfe von grafischen Terminal- und
Nichtterminalsymbolen definiert wird, was unter einem binären Baum verstanden wird
(vgl. NIEVERGELT&HINRICHS, S. 46 ff.).
2.2 Zugang über mathematische Kurven
Ein Beispiel sind die rekursiven Hilbert-Kurven.
H1
H2
H3
Im Unterricht können die Hilbert-Kurven H1, H2 und H3 vorgegeben werden.
Ausgehend von der elementaren Hilbert-Kurve H1 werden die Konstruktion von H2
aus H1 und von H3 aus H2 nachvollzogen. Die Schülerinnen und Schüler erkennen,
dass jeweils vier Hilbert-Kurven Hk zur Hilbert-Kurve Hk+1 zusammengesetzt werden.
Die vier Hilbert-Kurven werden in die jeweils gleiche Position zueinander gebracht
und mit Verbindungsstrecken, die in den Abbildungen aus Verständnisgründen
hervorgehoben sind, verbunden. Im Unterricht kann auch nur die Hilbert-Kurve H3
vorgegeben werden. Dann wird analysiert, dass die Hilbert-Kurve H3 aus vier HilbertKurven H2 und dass die Hilbert-Kurve H2 aus vier Hilbert-Kurven H1 besteht. Weitere
mathematische Kurven, die im Unterricht diskutiert werden können, sind z. B. die
Sierpinski-Kurven, die Schneeflockenkurven und der Baum des Pythagoras (vgl.
HEYDERHOFF, S. 14-20).
2.3 Zugang über Bilder
Das „Bild im Bild“ beim Fernsehen verdeutlicht Wiederholung mit Rekursion. Die
Zeichnung von M. C. Escher „Zeichnende Hände“ (1948) symbolisiert indirekte
Rekursion, bei der sich zwei Unterprogramme wechselseitig aufrufen. Auch
Phänomene mit Spiegeln werden mitunter der Rekursion zugeordnet (z. B. Aufenthalt
zwischen zwei parallelen Spiegelflächen oder Kaleidoskope). Matroschkas sind eine
schöne Illustration von Rekursion.
2.4 Zugang über Begriffsdefinitionen
Die Definition wichtiger informatischer Begriffe erfolgt auf rekursive Art. Ein erstes
Beispiel ist der Begriff Liste (vgl. z. B. FOTHE (2002)). Ein zweites Beispiel ist die
Definition eines binären Baumes:
Ein binärer Baum besteht aus einem Element (der Wurzel) und zwei binären
Bäumen (dem linken und dem rechten Teilbaum) oder es ist der leere binäre
Baum. Ein binärer Baum besteht aus endlich vielen Elementen.
Die Schülerinnen und Schüler sollen sich mit der Definition aktiv auseinander setzen.
Eine mögliche Aufgabe ist das Begründen, dass die nachfolgende Zeichnung einen
binären Baum darstellt:
A
B
D
C
E
F
G
H
Dabei wäre herauszuarbeiten, dass jeder Knoten, so z. B. auch E und F, zwei
Teilbäume besitzt. Bei E sind beide Teilbäume leer, bei F ist nur der linke Teilbaum
leer. Die Schülerinnen und Schüler sollen korrekte binäre Bäume angeben können.
2.5 Zugang über Texte
In natürlichen Sprachen lassen sich Strukturen finden, mit denen sich VorErfahrungen zur Rekursion gewinnen lassen. Der Satz „Dass dieser Wurm an
Würmern litt, die wiederum an Würmern litten…“ (Joachim Ringelnatz) und die
Ankündigung „Ich pflege jedem Sonntagskind, das sich zu mir zu finden weiß, drei
Wünsche zu gewähren. Die ersten zwei sind frei, den dritten kann ich verweigern,
wenn er töricht ist.“ (Wilhelm Hauff: Das kalte Herz) illustrieren einen Spezialfall der
Rekursion, die Endrekursion, sofern der dritte Wunsch wieder drei Wünsche sind. Ein
weiteres Beispiel sind Schachtelsätze, wie ein Eintrag in einem Lokalanzeiger.
Derjenige der den Täter der den Pfahl der an der Brücke die an dem Weg der nach Jena führt
liegt steht umgeworfen hat anzeigt erhält eine Belohnung.
Die Strukturierung kann mit Kommas erfolgen:
Derjenige, der den Täter, der den Pfahl, der an der Brücke, die an dem Weg, der nach Jena
führt, liegt, steht, umgeworfen hat, anzeigt, erhält eine Belohnung.
Möglich ist auch eine Strukturierung durch Ebenen:
Derjenige
erhält eine Belohnung.
der den Täter
anzeigt
der den Pfahl
umgeworfen hat
der an der Brücke
steht
die an dem Weg
liegt
der nach Jena führt
Auf jeder Ebene, bis auf die unterste, wird der Textfluss unterbrochen und später
fortgesetzt. Die Darstellung hat jedoch Grenzen, da auf den Ebenen vollkommen
andere Texte stehen.
2.6 Zugang über Handlungsabläufe
Mit dem folgenden Beispiel wird an die zweite Strukturierung des Schachtelsatzes
aus Abschnitt 2.5 angeknüpft.
Es klingelt. Ich lasse Anna herein und sage Anna guten Tag.
Es klingelt. Ich lasse Bert herein und sage Bert guten Tag. Es klingelt. Ich lasse Clara herein und sage Clara guten Tag. Es klingelt. Ich lasse Dirk herein und sage Dirk guten Tag. Bevor ich Anna, Bert und Clara begrüßen kann, klingelt es wieder. Meine Tätigkeit
wird von einer gleichartigen Tätigkeit unterbrochen. Ich begrüße erst Dirk, dann
Clara, Bert und Anna (vgl. Thüringer Abiturprüfung Grundfach Informatik 2001,
Aufgabe 1.1).
Ein rekursiver Algorithmus soll alle Anordnungen (Permutationen) von gegebenen
Elementen ermitteln. Der Algorithmus wird nachfolgend an den Elementen ▲,■,
und ● erläutert.
Mithilfe von Tauschoperationen werden die folgenden Viererfolgen erzeugt:
▲■
●
▲■●
▲●
■
●■
▲
Jedes der vier Elemente steht einmal an der vierten Position. Nach dem Erzeugen
einer jeden Viererfolge werden mithilfe von Tauschoperationen Dreierfolgen erzeugt.
Das Element an der vierten Position bleibt dabei fest. Zum Beispiel werden aus der
zweiten Viererfolge die folgenden Dreierfolgen erzeugt:
▲■●
▲●■
●■▲
Jedes der drei Elemente steht einmal an der dritten Position. Nach dem Erzeugen
einer jeden Dreierfolge werden mithilfe von Tauschoperationen Zweierfolgen erzeugt.
Die Elemente an der dritten und vierten Position bleiben dabei fest. Zum Beispiel
werden aus der dritten Dreierfolge die folgenden Zweierfolgen erzeugt:
●■▲
■●▲
Jedes der beiden Elemente steht einmal an der zweiten Position.
Das beschriebene Handlungsmuster ist unabhängig von der Anzahl an Elementen
einer Folge. Mit dem rekursiven Vorgehen werden die 24 Permutationen für die
gegebenen vier Elemente ermittelt.
2.7 Vergleichen von Rekursion und Iteration
Mit den sechs Zugängen kann Rekursion im Informatikunterricht in unterschiedlicher
Weise ohne Computereinsatz thematisiert werden. Der Autor hat im eigenen
Unterricht die Erfahrung gemacht, dass das Behandeln mehrerer Zugänge eine gute
Voraussetzung für das inhaltliche Verständnis von Rekursion ist. Rekursion und
Iteration können auf hohem Abstraktionsniveau verglichen werden. Bei beiden
handelt es sich um Formen der Wiederholung. Rekursion kann als Wiederholung
strukturgleicher Blöcke durch Schachtelung, Iteration als Wiederholung
strukturgleicher Blöcke durch Aneinanderreihung gekennzeichnet werden.
Iteration:
Rekursion:
3 Rekursive Problemlösungen auf dem Computer
In diesem Abschnitt sind exemplarisch zehn Probleme aufbereitet, die
unterschiedlichen Schwierigkeitsgrad besitzen und an denen Grundlagen zur
Rekursion auf der Ebene der Realisierung vermittelt werden können. Rekursive
Programme zur Berechnung von Gliedern der FIBONACCI-Zahlenfolge und anderer
rekursiv definierter Zahlenfolgen sowie von Funktionswerten der Fakultätsfunktion
fehlen nachfolgend, da diese Berechnungen aus Effizienzgründen iterativ oder mit
einer Tabelle erfolgen sollten (vgl. WINKLER&NIEVERGELT).
3.1 Überführen von Dezimal- in Dualzahlen
Die Schülerinnen und Schüler wissen, dass Computer intern im Dualsystem arbeiten.
Eine Konsequenz davon ist, dass eine Dezimalzahl, die vom Computer eingelesen
wird, vor der Verarbeitung in die gleichwertige Dualzahl zu überführen ist. Das
folgende Python-Programm löst diese Aufgabe:
def dual(zahl) :
ganz = zahl / 2
rest = zahl % 2
if rest == 0 :
zeichen = '0'
else :
zeichen = '1'
if ganz == 0 :
# Division ohne Rest
# Rest der Division
# Test auf Gleichheit
return zeichen
else :
return dual(ganz) + zeichen
n = input('ganze Zahl:')
print dual(n)
Im Unterricht kann an dem Beispiel erläutert werden, wie rekursive Programme vom
Computer abgearbeitet werden. In der vorletzten Zeile wird der Wert der
ganzzahligen Variablen n eingelesen (z. B. 113) und in der letzten Zeile wird mit
dual(n) die Funktion dual das erste Mal aufgerufen. Der Wert 113 wird an den
Wertparameter zahl der Funktion dual übergeben und es werden die Werte für die
lokalen Variablen berechnet: ganz=56, rest=1 und zeichen='1'. Mit dual(56) ruft sich
die Funktion dual rekursiv auf. Wir nennen dies den rekursiven Abstieg. Weitere
Selbstaufrufe sind dual(28), dual(14), dual(7), dual(3) und dual(1). Bei der
Abarbeitung von dual(1) werden die Werte ganz=0, rest=1 und zeichen='1' ermittelt.
Mit ganz=0 ist der rekursive Abbruch erreicht und die Funktion dual liefert das
Zeichen '1' als Funktionswert. An dieses Zeichen werden beim rekursiven Aufstieg
nacheinander die Zeichen '1', '1', '0', '0', '0' und '1' angehangen. Als Ergebnis entsteht
die Zeichenkette '1110001'. Jedes Mal, wenn die Funktion dual zur Abarbeitung
gebracht wird, werden die lokalen Variablen ganz, rest und zeichen erzeugt.
Rekursion wird bei dieser Problemlösung eingesetzt, um alle Divisionsreste zu
erzeugen und diese in umgekehrter Reihenfolge auszugeben. An dem Programm
wird deutlich, dass Rekursion in Programmen durch einen Selbstaufruf von
Unterprogrammen gekennzeichnet ist.
Ein anderes Einstiegsbeispiel wäre z. B. ein Programm, das eine Zeichenfolge auf
rekursive Art umdreht (erstes Zeichen abspalten, Rest-Zeichenfolge umdrehen,
abgespaltenes Zeichen an die umgedrehte Rest-Zeichenfolge anhängen).
3.2 Größter gemeinsamer Teiler
Taschenrechner, die mit gemeinen Brüchen operieren, können Ergebnisse kürzen,
indem sie ein Unterprogramm, das den Algorithmus nach EUKLID ausführt, zur
Abarbeitung bringen. Die Berechnung des ggT der ganzen Zahlen x und y kann
iterativ mit einer Schleife erfolgen (Python-Programm):
def ggT1(x, y) :
while y > 0 :
rest = x % y
x=y
y = rest
return x
a = 12
b = 40
g = ggT1(a, b)
print g
Die ggT-Berechnung lässt sich auch rekursiv formulieren:
def ggT2(x, y) :
if y == 0 :
return x
else :
return ggT2(y, x % y)
An diesem Beispiel erkennen die Schülerinnen und Schüler, wie eine iterative in
eine rekursive Problemlösung umgesetzt wird. Es entsteht Endrekursion, bei der
beim rekursiven Aufstieg keine Operationen mehr auszuführen sind.
3.3 Permutationen
Der Handlungsablauf von Abschnitt 2.6 kann z. B. in ein Oberon-Programm
umgesetzt werden. Entscheidend ist die Prozedur Perm. Bei vier Elementen ist
Perm(3) der erste Aufruf dieser Prozedur. Der rekursive Abbruch liegt vor, wenn eine
Folge nur aus einem Element besteht.
PROCEDURE Perm(n: INTEGER);
VAR k: INTEGER;
BEGIN
IF n = 0 THEN LoesungAusgeben ELSE
FOR k := n TO 0 BY -1 DO
Tausch(a[k], a[n]);
Perm(n - 1);
(* rekursiver Aufruf *)
Tausch(a[k], a[n])
END
END
END Perm;
Das Programm kann im Informatikunterricht beim Lösen von verschiedenen
Problemen genutzt werden. Ein Beispiel ist das Problem des Handlungsreisenden,
bei dem eine kürzeste Rundreise durch n Städte gesucht wird. Die Permutation 1 4 3
2 beschreibt die folgende Rundreise: Beginnend in der Stadt 1 geht es nacheinander
in die Städte 4, 3 und 2 und dann wieder zur Ausgangsstadt 1. Zur Lösung sind drei
Teile zu erarbeiten: Ermitteln aller Permutationen, Ermitteln der Länge einer jeden
Rundreise, Heraussuchen einer kürzesten Rundreise (vgl. Thüringer Abiturprüfung
Leistungsfach Informatik 2001, Aufgabe 3.2). Diese Methode des systematischen
Durchprobierens aller Varianten ist nur für wenige Städte anwendbar, da die
benötigte Rechenzeit exponentiell mit der Problemgröße, der Anzahl an Städten,
ansteigt.
3.4 Türme von Hanoi
Bei dem bekannten Spiel „Türme von Hanoi“ sind Scheiben von einem Feld auf ein
anderes in möglichst wenigen Schritten zu versetzen. Auf einem dritten Feld können
Scheiben zwischengelagert werden. Beim Versetzen sind zwei Spielregeln zu
beachten: Versetze immer nur eine Scheibe von einem Feld auf ein anderes und
lege stets eine kleinere Scheibe auf eine größere (vgl. 43. Mathematik-Olympiade, 1.
Stufe, Klasse 6, Aufgabe 430612).
Bei der rekursiven Lösung wird der Begriff Turm eingeführt und verwendet. Das
Versetzen eines Turmes, der aus k Scheiben besteht, wird auf das zweimalige
Versetzen eines Turms, der aus k-1 Scheiben besteht, zurückgeführt. Der rekursive
Abbruch liegt vor, wenn der zu versetzende Turm aus 0 Scheiben besteht. Nach
dieser Vorschrift sind ganze Türme zu versetzen, obwohl nach den Spielregeln nur
einzelne Scheiben bewegt werden dürfen. Die Schülerinnen und Schüler sollen
erkennen, dass dieser Widerspruch durch wiederholtes Anwenden der Vorschrift
aufgelöst wird. Die nachfolge Tabelle illustriert dies für einen Turm, der aus vier
Scheiben besteht. Die rechte Spalte ist die Einzige, die ausschließlich direkt
ausführbare Handlungen enthält.
Turm(1, 1, 3)
Turm(2, 1, 2)
Scheibe(2, 1, 2)
Turm(1, 3, 2)
Turm(3, 1, 3)
Scheibe(3, 1, 3)
Scheibe(3, 1, 3)
Turm(1, 2, 1)
Turm(2, 2, 3)
Scheibe(2, 2, 3)
Turm(1, 1, 3)
Turm(4, 1, 2)
Scheibe(4, 1, 2)
Scheibe(4, 1, 2)
Scheibe(4, 1, 2)
Turm(1, 3, 2)
Turm(2, 3, 1)
Scheibe(2, 3, 1)
Turm(1, 2, 1)
Turm(3, 3, 2)
Scheibe(3, 3, 2)
Scheibe(3, 3, 2)
Turm(1, 1, 3)
Turm(2, 1, 2)
Scheibe(2, 1, 2)
Turm(1, 3, 2)
Turm(0, 1, 2)
Scheibe(1, 1, 3)
Turm(0, 2, 3)
Scheibe(2, 1, 2)
Turm(0, 3, 1)
Scheibe(1, 3, 2)
Turm(0, 1, 2)
Scheibe(3, 1, 3)
Turm(0, 2, 3)
Scheibe(1, 2, 1)
Turm(0, 3, 1)
Scheibe(2, 2, 3)
Turm(0, 1, 2)
Scheibe(1, 1, 3)
Turm(0, 2, 3)
Scheibe(4, 1, 2)
Turm(0, 3, 1)
Scheibe(1, 3, 2)
Turm(0, 1, 2)
Scheibe(2, 3, 1)
Turm(0, 2, 3)
Scheibe(1, 2, 1)
Turm(0, 3, 1)
Scheibe(3, 3, 2)
Turm(0, 1, 2)
Scheibe(1, 1, 3)
Turm(0, 2, 3)
Scheibe(2, 1, 2)
Turm(0, 3, 1)
Scheibe(1, 3, 2)
Turm(0, 1, 2)
Scheibe(1, 1, 3)
Scheibe(2, 1, 2)
Scheibe(1, 3, 2)
Scheibe(3, 1, 3)
Scheibe(1, 2, 1)
Scheibe(2, 2, 3)
Scheibe(1, 1, 3)
Scheibe(4, 1, 2)
Scheibe(1, 3, 2)
Scheibe(2, 3, 1)
Scheibe(1, 2, 1)
Scheibe(3, 3, 2)
Scheibe(1, 1, 3)
Scheibe(2, 1, 2)
Scheibe(1, 3, 2)
Die n Scheiben bekommen der Größe nach die Nummern von 1 bis n. Die kleinste
Scheibe trägt die Nummer 1. Turm(k, a, b) bedeutet: Versetze den Turm, der aus k
Scheiben besteht, von Feld a nach Feld b. Scheibe(k, a, b) bedeutet: Versetze
Scheibe k von Feld a nach Feld b.
Die rekursive Vorschrift ist Ausgangspunkt für die Programmentwicklung (vgl. z. B.
FOTHE&KERNER (1988)). Aus der rekursiven Lösung lassen sich iterative herleiten.
Eine Variante ist das wechselweise Anwenden der beiden folgenden Regeln: Lege
die kleinste Scheibe eins weiter (entweder stets rechts herum oder stets links
herum). Lege eine andere Scheibe.
3.5 Quicksort
Der wichtige Sortieralgorithmus Quicksort besitzt eine rekursive Struktur. Beim
Abarbeiten von Sort(L, R) werden die Elemente der Folge von aL bis aR in die richtige
Reihenfolge gebracht. Die Prozedur Sort enthält zwei rekursive Aufrufe, und zwar für
die linke Teilfolge der Elemente von aL bis aK und die rechte Teilfolge der Elemente
von aI bis aR (Methode Teile und Herrsche). Der rekursive Abbruch liegt vor, wenn
eine Teilfolge nur aus einem Element besteht. Das Zeit- und Speicherverhalten von
Quicksort kann im Unterricht auf der Grundlage eines einfachen Modells thematisiert
werden (vgl. FOTHE (2003)). Beim Speicherverhalten sind der Speicherplatz für die
Elemente und die Einträge im Stack zu berücksichtigen. Im besten Fall liegen
gleichzeitig bis zu ld n Einträge im Stack vor, im schlechtesten Fall sind es n-1. An
dem Programm „Quicksort“ kann die interne Abarbeitung rekursiver Unterprogramme
im Unterricht auf der Ebene einer Modellvorstellung thematisiert werden. Mit einem
Stack (Stapel, Keller), der vom Laufzeitsystem der Programmiersprache automatisch
verwaltet wird, kann ein rekursiv arbeitendes Programm auf einem Computer nach
dem von-Neumann-Rechnermodell, der iterativ arbeitet, zur Abarbeitung gebracht
werden. Bei jedem rekursiven Unterprogrammaufruf werden die Werte der Parameter
und die der lokalen Variablen sowie die Rückkehradresse im Stack gespeichert und
später wieder vom Stack geholt.
3.6 Suchbaum
Auf rekursive Datenstrukturen kann auf rekursive Art zugegriffen werden. Ein Beispiel
ist das Ausgeben eines binären Baumes mit der Methode Inorder, bei der zuerst der
linke Teilbaum ausgegeben wird, dann die Daten der Wurzel und anschließend der
rechte Teilbaum. Diese Vorschrift wird rekursiv auf jeden Teilbaum angewandt. Für
den unter 2.4 angegebenen binären Baum ergibt sich die Zeichenfolge D, B, E, A, F,
H, G, C. Bei einem speziellen binären Baum, dem Suchbaum, sind alle Daten im
linken Teilbaum kleiner als die Daten der Wurzel und die Daten der Wurzel kleiner
als alle Daten im rechten Teilbaum. Diese Regel wird rekursiv auf jeden Teilbaum
angewandt. Aus den Definitionen von Inorder und Suchbaum folgt, dass die Methode
Inorder bei einem Suchbaum die Daten der Knoten in der sortierten Reihenfolge
liefert.
3.7 Speichern von Bildern
0
0
0
0
1
1
0
0
0
0
0
0
1
1
1
0
1
1
0
0
1
1
0
0
1
1
0
0
0
0
0
0
0
0
0
0
1
1
1
1
0
0
0
0
1
1
1
1
0
0
0
0
1
1
1
1
0
0
0
0
1
1
1
1
Das Bild wird in vier Quadranten aufgeteilt. Der erste Quadrant (rechts-oben) besteht
ausschließlich aus Nullen. Daher wird für ihn eine 0 gespeichert. Der zweite
Quadrant (links-oben) besteht aus Nullen und Einsen. Er wird wiederum in
Quadranten zerlegt. Diese vier Quadranten bestehen einheitlich aus jeweils vier
Nullen oder aus vier Einsen. Für den zweiten Quadranten wird (1,0,0,0) gespeichert.
Der dritte Quadrant (links-unten) besteht aus Nullen und Einsen. Er wird weiter
zerlegt und es zeigt sich, dass zwei dieser Quadranten nur aus Nullen bzw. nur aus
Einsen bestehen und dass die beiden anderen Quadranten gemischt sind. Es ergibt
sich ((0,1,1,0),1,(1,0,0,0),0). Der vierte Quadrant (rechts-unten) besteht einheitlich
aus Einsen. Daher wird für ihn eine 1 gespeichert. Das ganze Bild kann mit
(0,(1,0,0,0),((0,1,1,0),1,(1,0,0,0),0),1) gespeichert werden. Diese Zeichenfolge könnte
in einen Viererbaum überführt werden und es könnten rekursive Unterprogramme zur
Arbeit mit dem Baum angegeben werden. Ein Beispiel dafür ist das Drehen des
Bildes um 90°, was durch Rotation der Knoten auf allen Ebenen des Baumes
realisiert wird (vgl. DEWDNEY, S. 340-346).
3.8 Suchen in einem Labyrinth
Die Labyrinthsuche ist ein Beispiel für das Problemlösungsverfahren Backtracking.
Gesucht werden in einem rechteckigen Labyrinth alle Wege von einem Start- zu
einem Zielfeld. Als Modell für das Labyrinth eignet sich ein zweidimensionales Array,
dessen Elemente Zeichen sind. Nullen stellen die Wege, Einsen die Mauern oder
Hecken dar. Zweien fassen das Labyrinth ein. Das Zeichen A symbolisiert das Startund das Zeichen B das Zielfeld. Die Prozedur Schritt führt einen zulässigen Schritt in
dem Labyrinth aus und garantiert, dass im Suchprozess alle Varianten ausprobiert
und dass Zyklen bei der Suche ausgeschlossen werden. Nach einem zulässigen
Schritt erfolgt ein rekursiver Aufruf der Prozedur Schritt (vgl. FOTHE (2001)). In einer
Projektarbeit können die Schülerinnen und Schüler ein vorgegebenes Programm für
rechteckige Labyrinthe analysieren und es dann z. B. so modifizieren, dass es bei
räumlichen Labyrinthen funktioniert. Bei einem räumlichen Labyrinth gibt es mehrere
ebene Labyrinthe übereinander, die durch Leitern an einem oder an mehreren
Feldern miteinander verbunden sind.
3.9 Hilbert-Kurven
Das Problem kann in zwei Teilprobleme aufgeteilt werden. Das erste Teilproblem
besteht darin, die Ordnung der Hilbert-Kurve einzulesen und eine Folge von
Zeichenanweisungen zu erzeugen. Für die Hilbert-Kurve H2 (vgl. Abschnitt 2.2) ergibt
sich die Folge SWNWWSESWSEENES. Das zweite Teilproblem besteht darin, diese
Zeichenanweisungen einzulesen, zu interpretieren und eine Folge von gleich langen
Strecken auf dem Bildschirm auszugeben. Das Programm zur Lösung des ersten
Teilproblems enthält die vier rekursiv arbeitenden Prozeduren A, B, C und D.
Nachfolgend ist exemplarisch der Quelltext der Prozedur A in Oberon angegeben
(die anderen drei Prozeduren besitzen ähnlichen Aufbau).
PROCEDURE A(i: INTEGER);
BEGIN
IF i > 0 THEN
D(i - 1); Out.Char("W"); (* ein Schritt nach Westen *)
A(i - 1); Out.Char("S"); (* ein Schritt nach Sueden *)
A(i - 1); Out.Char("E"); (* ein Schritt nach Osten *)
B(i - 1)
END
END A;
Ein anderes Vorgehen beim Zeichnen
NIEVERGELT&HINRICHS, S. 36 ff.
von
Hilbert-Kurven
beschreiben
3.10 Syntaxanalyse
Eine Möglichkeit für die Syntaxanalyse ist das Befolgen der Regel, dass sich die
grammatikalische Struktur einer Sprache in der Struktur des Parsers widerspiegeln
soll. Besitzt eine Sprachbeschreibung eine rekursive Struktur, so wird das
entsprechende Programm zur Syntaxanalyse ebenfalls rekursiv aufgebaut sein (vgl.
WIRTH (1986)). Das Erarbeiten eines einfachen Parsers eignet sich als Projektarbeit
für besonders interessierte Schülerinnen und Schüler.
4 Resümee
Das Thema Rekursion beinhaltet sowohl theoretische als auch praktische Aspekte.
Theoretisches und Praktisches lässt sich bei der Behandlung im Unterricht gut
miteinander verzahnen. Im Unterricht lassen sich Probleme mit Bezug zu Rekursion
bearbeiten, die unterschiedlichen Komplexitäts- und Schwierigkeitsgrad besitzen.
Bereits im Anfangsunterricht können einfache rekursive Problemlösungen erarbeitet
werden. Die in der SI erworbenen Kenntnisse und Fähigkeiten lassen sich ohne
Brüche schrittweise bis hin zum Bearbeiten von größeren Projekten in der SII
ausbauen. Die in dieser Arbeit angegebenen Probleme stammen aus
unterschiedlichen Gebieten und besitzen teilweise erhebliche Relevanz in
Anwendungen.
Das Thema „Rekursion und Iteration“ ist eines der Themen, die ich gemeinsam mit
einigen Thüringer Gymnasien ab 2004 genauer untersuchen möchte.
Jürgen F. H. Winkler danke ich für kritische Hinweise zu Entwürfen dieses Beitrags.
5 Literatur
Barron, D. W.: Rekursive Techniken in der Programmierung. Teubner Leipzig 1971
Baumann, R.: Didaktik der Informatik. 2. Aufl. Klett Stuttgart, München, Düsseldorf, Leipzig 1996
Dewdney, A. K.: Der Turing Omnibus. Eine Reise durch die Informatik mit 66 Stationen. Springer
Berlin, Heidelberg, New York 1995
Fothe, M.; Kerner, I. O.: Problem des Lucas. Wurzel, Jena 2/88, S. 18-23
Fothe, M.: Problemlösen mit OBERON. Konzeption und Einsatz eines elektronischen Lehrbuchs. LOG
IN 21 (2001) Heft 2, S. 33-40
Fothe, M.: Problemlösen mit Python. Reihe „Materialien“, Heft 72 des ThILLM Bad Berka 2002
Fothe, M.: Zeitverhalten von Sortierverfahren – Beispiele für experimentelles Arbeiten im
Informatikunterricht. In: Hubwieser, P. (Hrsg.): Informatische Fachkonzepte im Unterricht, INFOS
2003. Lecture Notes in Informatics (LNI). Bonn 2003, S. 111-120
Heyderhoff, P. (Hrsg.): Bundeswettbewerb Informatik. Aufgaben und Lösungen, Band 2. Klett Stuttgart
1990
Hubwieser, P.: Didaktik der Informatik. Grundlagen, Konzepte, Beispiele. Springer Berlin, Heidelberg,
New York 2000
Nievergelt, J.; Hinrichs, K. H.: Algorithms and Data Structures. With Applications to Graphics and
Geometry. Prentice Hall Englewood Cliffs 1993
Rechenberg, P.: Quo vadis Informatik? LOG IN 17 (1997) Heft 1, S. 25-32
Reiser, M.; Wirth, N.: Programming in Oberon. Steps beyond Pascal and Modula. ACM Press, New
York; Addison-Wesley, Wokingham, Reading 1992
Schubert, S.; Schwill, A.: Didaktik der Informatik. Spektrum Akademischer Verlag Heidelberg, Berlin
2004
Wagenknecht, C.: Rekursion. Ein didaktischer Zugang mit Funktionen. Dümmler Bonn 1994
Winkler, J. F. H.; Nievergelt, J.: Wie soll die Fakultätsfunktion programmiert werden? InformatikSpektrum 12, 4 (1989) 220-221
Wirth, N.: Compilerbau. 4. Aufl. Teubner Stuttgart 1986
Autor:
Prof. Dr. Michael Fothe
Casio-Stiftungsprofessur
Didaktik Informatik/Mathematik
Friedrich-Schiller-Universität Jena
Fakultät für Mathematik und Informatik
07740 Jena
E-Mail [email protected]
Zugehörige Unterlagen
Herunterladen