Qualifikationsphase Q1 · Themenfeld Q1.3

Q1.3 – Rekursion als Modellierungsstrategie

Probleme über Teilprobleme beschreiben, visualisieren und begründet mit Iteration vergleichen

Q1.2 hat Such- und Sortieralgorithmen als Verfahren untersucht: lineare Suche, binäre Suche, einfache quadratische Sortieralgorithmen, Laufzeitbewertung und auf erhöhtem Niveau einen effizienten Sortieralgorithmus. Dort ging es vor allem darum, Strategien im Ablauf zu lesen: Welcher Vergleich findet statt, welcher Bereich bleibt übrig, wie wächst der Aufwand?

Q1.3 verschiebt nun den Blick. Nicht mehr nur der Ablauf eines Verfahrens steht im Vordergrund, sondern die Struktur des Problems. Rekursion beschreibt eine Aufgabe so, dass sie auf eine kleinere Aufgabe derselben Art zurückgeführt wird. Erst danach wird diese Idee als Selbstaufruf in einer Methode implementiert.

Dadurch entsteht eine Brücke zwischen Algorithmik und Modellierung: Manche Probleme wirken rekursiv besonders natürlich, obwohl sie oft auch iterativ formulierbar sind. Entscheidend ist deshalb nicht die Frage, welche Schreibweise moderner wirkt, sondern welche Darstellung die Problemstruktur, den Speicherbedarf und die Laufzeitfolgen am besten sichtbar macht.

Kerncurriculum
Kerncurriculum kompakt
Rekursion nach grundlegendem und erhöhtem Niveau
Grundlegendes Niveau (Grundkurs und Leistungskurs)
Erhöhtes Niveau (Leistungskurs)
Anschluss an Q1.2
Von Q1.2 zu Q1.3: vom Ablauf zur Problemstruktur
Bekannte Such- und Sortierverfahren als Brücke zur rekursiven Modellierung

Q1.2 wird hier nicht wiederholt. Die bekannten Verfahren dienen als Referenzpunkte: lineare Suche prüft nacheinander, binäre Suche halbiert einen sortierten Suchraum, Insertion Sort baut einen sortierten Bereich auf, Quicksort trennt Daten um ein Pivot. Q1.3 fragt nun: Welche dieser Ideen lassen sich als Folge kleinerer Teilprobleme derselben Art beschreiben?

Bekannter Bezugspunkt aus Q1.2 Frage in Q1.2 Frage in Q1.3
Lineare Suche Wie viele Elemente werden nacheinander geprüft? Ist „Suche ab Index i“ ein kleineres Problem derselben Art?
Binäre Suche Wie halbiert der Vergleich mit der Mitte den Suchraum? Wie wird aus einem Intervall ein kleineres Intervall als neues Teilproblem?
Insertion Sort Wie wächst der sortierte Bereich iterativ? Kann erst ein kleineres Teilarray sortiert und danach ein Element eingefügt werden?
Quicksort Warum kann ein effizienter Sortieralgorithmus typischerweise günstiger skalieren? Wie entstehen mehrere rekursive Teilprobleme durch Pivot-Zerlegung?

Damit ändert sich die Leitfrage. Q1.2 untersuchte Such- und Sortierstrategien und deren Laufzeit. Q1.3 untersucht, ob ein Verfahren besser als Schleifensteuerung oder als rekursive Teilproblemstruktur modelliert werden kann.

Rekursion verstehen
Rekursion verstehen: Selbstähnlichkeit, Teilproblem, Basisfall
Die Idee vor dem Code entwickeln

Der Einstieg in Rekursion ist nicht der Satz „Eine Methode ruft sich selbst auf“. Das ist nur die spätere Implementationsform. Fachlich beginnt Rekursion mit einer Strukturidee: Eine Aufgabe wird auf eine kleinere Aufgabe derselben Art zurückgeführt.

Grundidee
Rekursion liegt vor, wenn ein Problem so beschrieben wird, dass seine Lösung auf der Lösung eines oder mehrerer kleinerer Teilprobleme desselben Typs beruht. Damit die Beschreibung endet, braucht sie einen direkt lösbaren Fall.

Anschauliche Idee: Treppe

Eine Treppe mit n Stufen kann man rekursiv beschreiben: Wenn keine Stufe mehr übrig ist, ist man fertig. Sonst nimmt man eine Stufe und hat danach wieder dasselbe Problem mit n - 1 Stufen. Die Aufgabe verändert sich nicht grundsätzlich, sie wird nur kleiner.

Anschauliche Idee: verschachtelte Struktur

Auch Verzeichnisse, Bäume oder verschachtelte Klammern wirken rekursiv: In einem Ordner können wieder Ordner liegen; in einem Teilbaum können wieder Teilbäume liegen. Eine Regel kann also auf ein Ganzes und auf seine Teile angewendet werden.

Begriff Bedeutung Leitfrage
Teilproblem Kleinere Aufgabe derselben Art. Was bleibt übrig, wenn ein Schritt erledigt ist?
Basisfall / Rekursionsanker Direkt lösbarer Fall ohne weiteren Selbstaufruf. Wann ist das Problem klein genug?
Terminierungsbedingung Bedingung, die den rekursiven Abstieg beendet. Woran erkennt das Verfahren, dass es stoppen muss?
Rekursionsschritt Regel, die das Problem verkleinert und erneut anwendet. Wie wird aus dem Problem ein kleineres Problem?
Rekursionsaufruf Selbstaufruf der Methode mit veränderten Parametern. Welche Daten beschreiben das neue Teilproblem?
Grundstrukturen
Grundstrukturen rekursiver Implementierung
Basisfall, Parameterübergabe, Rekursionsschritt, einfache und mehrfache Rekursion

In einer Implementierung wird die Problemstruktur zur Methode. Die Methode prüft zuerst den Basisfall. Wenn dieser nicht erreicht ist, ruft sie sich mit veränderten Parametern erneut auf. Die Parameter tragen den Zustand des aktuellen Teilproblems.

Einfache lineare Rekursion: Summe bis n

int summeBis(int n) {
    if (n <= 0) return 0;       // Basisfall / Terminierung
    return n + summeBis(n - 1); // Rekursionsschritt
}

Das Teilproblem lautet: „Berechne die Summe bis n - 1“. Pro Aufruf entsteht höchstens ein weiterer Rekursionsaufruf. Deshalb ist dies einfache Rekursion.

Parameterübergabe als Zustandswechsel

  • n im aktuellen Aufruf: beschreibt das aktuelle Teilproblem.
  • n - 1 im nächsten Aufruf: beschreibt ein kleineres Teilproblem.
  • Rückgabewert: liefert das Ergebnis des Teilproblems zurück.
  • Ausdruck n + ...: kombiniert aktuelles Stück und Teilergebnis.

Parameterübergabe ersetzt hier nicht einfach eine Schleifenvariable. Sie modelliert, welche Restaufgabe im nächsten Aufruf gelöst werden soll.

Mehrfache Rekursion vorsichtig lesen
Mehrfache Rekursion bedeutet, dass ein Aufruf mehrere rekursive Folgeaufrufe erzeugt. Das kann fachlich passend sein, aber auch schnell teuer werden, wenn dieselben Teilprobleme mehrfach berechnet werden.

Fibonacci als Warnbeispiel

int fibonacci(int n) {
    if (n <= 1) return n;
    return fibonacci(n - 1) + fibonacci(n - 2);
}

Dieses Beispiel zeigt mehrfache Rekursion gut, ist aber als naive Implementierung ineffizient: Viele Werte werden mehrfach berechnet, etwa fibonacci(3) in mehreren Ästen des Aufrufbaums.

Woran gute rekursive Implementierungen erkennbar sind

  • Der Basisfall ist vor dem rekursiven Aufruf erreichbar.
  • Jeder Rekursionsschritt verkleinert das Problem nachvollziehbar.
  • Die Parameter beschreiben das neue Teilproblem eindeutig.
  • Die Rückgabephase ist klar: Was wird nur weitergereicht, was wird kombiniert?
Visualisierung
Rekursive Abläufe visualisieren: Aufrufstapel und Rückgabe
Hinabsteigen, Basisfall erreichen, Ergebnisse zurückgeben

Eine Visualisierung rekursiver Abläufe muss mehr zeigen als eine dekorative Baumform. Sie soll verständlich machen, welche Aufrufe gerade offen sind, wann der Basisfall erreicht wird und in welcher Reihenfolge Rückgabewerte wieder nach oben wandern.

Aufrufstapel / Stack
Der Aufrufstapel speichert laufende Methodenaufrufe. Jeder rekursive Aufruf legt einen neuen Eintrag mit Parametern, lokalen Variablen und Rücksprungstelle ab. Erst wenn ein Aufruf einen Wert zurückgibt, wird dieser Eintrag wieder entfernt. Die Rekursionstiefe ist die Anzahl gleichzeitig aktiver rekursiver Aufrufe und beeinflusst den Speicherbedarf.

Aufrufphase bei summeBis(4)

Beim Hinabsteigen entstehen neue Aufrufe. Jeder wartet darauf, dass das kleinere Teilproblem gelöst wird.

Rückgabephase bei summeBis(4)

Beim Zurückgeben werden die offenen Rechnungen in umgekehrter Reihenfolge abgeschlossen. Deshalb braucht Rekursion Speicher für noch nicht beendete Aufrufe.

Phase Was passiert? Warum ist das wichtig?
Hinabsteigen Das Problem wird durch neue Aufrufe kleiner gemacht. Die Terminierung hängt daran, dass die Parameter wirklich Richtung Basisfall laufen.
Basisfall Ein Teilproblem wird direkt gelöst. Ohne Basisfall entsteht Nichttermination oder ein Stack-Fehler.
Rückgabe Ergebnisse werden zurückgereicht und ggf. kombiniert. Hier entsteht häufig erst das eigentliche Gesamtergebnis.
Grafiken und Funktionen
Rekursive Grafiken und mathematische Funktionen
Selbstähnlichkeit in Bildern und lineare Rekursion in Funktionen

Rekursion ist nicht auf Such- und Sortierverfahren beschränkt. Sie wird besonders anschaulich, wenn eine Struktur kleinere Versionen ihrer selbst enthält: ein Ast verzweigt in kleinere Äste, eine Figur enthält kleinere Kopien, eine mathematische Funktion verweist auf einen kleineren Eingabewert.

Rekursive Grafik: Aststruktur

Ein Zeichenverfahren kann rekursiv sein: Zeichne einen Ast. Wenn der Ast noch lang genug ist, zeichne an seinem Ende zwei kleinere Äste nach derselben Regel. Der Basisfall lautet zum Beispiel: „Zeichne nicht weiter, wenn die Länge zu klein ist.“

void zeichneAst(double laenge) {
    if (laenge < 10) return;          // Basisfall

    zeichneLinie(laenge);
    drehe(-30);
    zeichneAst(laenge * 0.65);        // linker Teilast
    drehe(60);
    zeichneAst(laenge * 0.65);        // rechter Teilast
    drehe(-30);
}

Mathematische Funktion: Fakultät

Die Fakultät zeigt lineare Rekursion in einer kompakten Form: n! ist n * (n - 1)!, und 1! bzw. 0! ist direkt 1. Der rekursive Verweis ist fachlich schon in der Definition enthalten.

long fakultaet(int n) {
    if (n <= 1) return 1;
    return n * fakultaet(n - 1);
}

Für den Einstieg reicht ein solches Beispiel oft besser als viele parallele mathematische Funktionen: Basisfall, Rekursionsschritt und Rückgabephase bleiben gut sichtbar.

Der Unterschied liegt in der Form der Teilprobleme. Fakultät und Summe verkleinern linear. Die rekursive Grafik erzeugt mehrere Teilfiguren und ist damit ein anschauliches Beispiel für mehrfache Rekursion.

Rekursion versus Iteration
Rekursion versus Iteration
Dieselbe Algorithmusidee über Schleife oder Teilproblemfolge beschreiben

Iteration steuert Wiederholung explizit über Schleifen und Zustandsvariablen. Rekursion steuert Wiederholung über neue Aufrufe mit veränderten Parametern. Beide können denselben Algorithmus beschreiben. Rekursion ist nicht automatisch effizienter, und Iteration ist nicht automatisch verständlicher.

Fokussierter Vergleich: binäre Suche

Iterative Darstellung
int binaereSucheIterativ(int[] a, int suchwert) {
    int links = 0;
    int rechts = a.length - 1;

    while (links <= rechts) {
        int mitte = (links + rechts) / 2;
        if (a[mitte] == suchwert) return mitte;
        if (a[mitte] < suchwert) links = mitte + 1;
        else rechts = mitte - 1;
    }
    return -1;
}
Rekursive Darstellung
int binaereSucheRekursiv(int[] a, int suchwert, int links, int rechts) {
    if (links > rechts) return -1;

    int mitte = (links + rechts) / 2;
    if (a[mitte] == suchwert) return mitte;
    if (a[mitte] < suchwert) {
        return binaereSucheRekursiv(a, suchwert, mitte + 1, rechts);
    }
    return binaereSucheRekursiv(a, suchwert, links, mitte - 1);
}
Leitfrage Iteration Rekursion
Welche Variante bildet die Problemstruktur besser ab? Gut, wenn der Ablauf als fortgeschriebener Zustand gelesen wird. Gut, wenn das Intervall als neues Teilproblem verstanden wird.
Welche Variante ist speicherschonender? Meist günstiger, weil nur wenige Variablen weitergeführt werden. Benötigt zusätzliche Stack-Einträge pro Rekursionsstufe.
Welche Variante ist leichter zu lesen? Übersichtlich, wenn Schleifenbedingungen und Zustandsupdates klar bleiben. Übersichtlich, wenn Basisfall und Teilproblemfolge klar formuliert sind.
Was ist der wichtigste Denkfehler? Iteration ist nicht automatisch „einfacher“. Rekursion ist nicht automatisch „effizienter“.
Kurze Bewertung
Bei der binären Suche beschreiben beide Varianten dieselbe Halbierungsstrategie. Die iterative Form ist speicherschonend und nah am Kontrollfluss. Die rekursive Form macht die Folge kleinerer Suchintervalle fachlich sehr deutlich. Die begründete Wahl hängt daher von Modellnähe, Lesbarkeit und Speicherbedarf ab.
Teile und herrsche
Teile-und-herrsche
Brücke zwischen binärer Suche, Quicksort und rekursiver Problemzerlegung
Prinzip
Teile-und-herrsche bedeutet: Problem zerlegen, Teilprobleme lösen, Ergebnisse nutzen oder zusammenführen. Viele Teile-und-herrsche-Verfahren sind rekursiv formulierbar, aber nicht jede Rekursion ist automatisch Teile-und-herrsche.

1. Zerlegen

Ein Suchraum wird halbiert oder eine Liste durch ein Pivot getrennt.

2. Teilprobleme lösen

Das kleinere Problem wird iterativ oder rekursiv weiterbearbeitet.

3. Ergebnis nutzen

Ein Treffer wird zurückgegeben oder sortierte Teilbereiche ergeben die Gesamtlösung.

Beispiel Art der Verkleinerung Einordnung
Summe / Fakultät n wird zu n - 1. Lineare Rekursion, aber kein klassisches Teile-und-herrsche.
Binäre Suche Der Suchraum wird halbiert, aber nur eine Hälfte wird weiterverfolgt. Wichtige Brücke: Die Teilproblemidee wird sichtbar, ohne zwei Ergebnisse zu kombinieren.
Quicksort Die Liste wird in kleinere und größere Werte um ein Pivot getrennt. Klassisches rekursives Teile-und-herrsche mit mehreren Teilproblemen.

Quicksort als rekursives Sortierbeispiel

void quicksort(int[] a, int links, int rechts) {
    if (links >= rechts) return;          // Basisfall

    int pivotIndex = partition(a, links, rechts);
    quicksort(a, links, pivotIndex - 1);  // linkes Teilproblem
    quicksort(a, pivotIndex + 1, rechts); // rechtes Teilproblem
}

Quicksort ist typischerweise effizient, wenn die Pivotwahl ausgewogene Teilbereiche erzeugt. Bei ungünstiger Pivotwahl können die Teilprobleme fast so groß wie vorher bleiben; dann kann Quicksort im Worst Case quadratische Laufzeit erreichen.

Backtracking
Erhöhtes Niveau: Backtracking
Rekursionsnahes Suchen im Entscheidungsraum

Backtracking ist ein rekursionsnahes Suchverfahren für Entscheidungsräume. Eine Lösung wird schrittweise aufgebaut. Führt eine Entscheidung in eine Sackgasse, wird sie zurückgenommen und eine andere Möglichkeit ausprobiert.

Grundmuster

  1. Prüfe, ob die aktuelle Teillösung bereits vollständig ist.
  2. Bestimme mögliche nächste Entscheidungen.
  3. Wähle eine Entscheidung und gehe rekursiv weiter.
  4. Wenn sie nicht trägt, mache die Entscheidung rückgängig.

Das Zurücknehmen ist fachlich entscheidend: Der Algorithmus erkundet nicht nur eine lineare Folge, sondern verzweigt im Raum möglicher Lösungen.

Beispiele

In einem Labyrinth wird ein Weg Schritt für Schritt markiert. Wenn eine Wand oder Sackgasse erreicht wird, geht das Verfahren zurück. Beim n-Damen-Problem oder bei Sudoku werden Belegungen ausprobiert, geprüft und bei Widerspruch wieder entfernt.

boolean sucheLoesung(Zustand z) {
    if (istLoesung(z)) return true;

    for (Entscheidung e : moeglicheEntscheidungen(z)) {
        wendeAn(z, e);
        if (sucheLoesung(z)) return true;
        macheRueckgaengig(z, e);
    }
    return false;
}

Backtracking passt deshalb gut zum erhöhten Niveau: Es verbindet Rekursion, Entscheidung, Zustandsänderung und Rücknahme zu einem Suchverfahren, ohne dass die Seite in ein vollständiges Sudoku- oder n-Damen-Kapitel ausufern muss.

Tool-Vergleich
Tool-gestützte Vergleichsanalyse
Modellierungsformen an derselben Problemidee untersuchen

Das Werkzeug Such- und Sortieralgorithmen visualisieren ist für Q1.3 ein Vergleichsinstrument. Es bietet lineare und binäre Suche sowie Insertion Sort und Quicksort in iterativen und rekursiven Varianten. Sichtbar werden unter anderem Schritttexte, Markierungen, Vergleichszahlen, Tausch- bzw. Verschiebeoperationen, der Suchschlüssel und eine Vergleichskurve über mehrere Läufe.

Q1.3-Fokus im Tool
In Q1.2 stand vor allem Ablauf und Laufzeit im Mittelpunkt. In Q1.3 wird dieselbe Oberfläche genutzt, um Modellierungsformen zu vergleichen: Welche Teilproblemfolge entsteht, welche Parameter ändern sich, und welche Laufzeit- oder Speicherfolgen lassen sich begründen?

Geeignete Vergleiche

  • Lineare Suche iterativ und rekursiv: Indexfortschritt versus Teilproblem „ab Index i“.
  • Binäre Suche iterativ und rekursiv: Grenzen im Schleifenzustand versus Intervallparameter.
  • Insertion Sort iterativ und rekursiv: wachsender sortierter Bereich versus sortiertes Teilarray.
  • Quicksort rekursiv und iterativ: rekursive Aufrufe versus expliziter Stack für Teilbereiche.

Saubere Auswertung

  1. Wähle für zwei Varianten dieselbe Array-Größe und dieselbe Problemidee.
  2. Nutze Einzelschritte, um Parameteränderungen oder Teilbereiche zu protokollieren.
  3. Vergleiche die Verlaufslinien der Vergleichszahlen erst danach.
  4. Begründe zusätzlich den Speicheraspekt: Das Tool zeigt keinen eigenen Call-Stack-Viewer.

Damit bleibt die Toolaussage präzise: Es visualisiert Abläufe, Markierungen und Kennzahlen rekursiver und iterativer Varianten. Die Aufrufstruktur und der Speicherbedarf müssen aus Schritttext, Parametern und dem in dieser Seite entwickelten Stackmodell fachlich rekonstruiert werden.

Reflexion
Reflexion: begründete Verfahrenswahl
rekursiv, iterativ oder teile-und-herrsche bewusst auswählen

Am Ende von Q1.3 steht keine Regel „Rekursion ist besser“ oder „Iteration ist besser“. Die fachliche Leistung besteht darin, die Modellierungsentscheidung zu begründen.

Prüffrage Worauf sie zielt
Gibt es kleinere Teilprobleme derselben Art? Grundlage für rekursive Modellierung.
Ist der Basisfall eindeutig erreichbar? Terminierung und fachliche Korrektheit.
Welche Parameter beschreiben das Teilproblem? Saubere Implementierung und Lesbarkeit.
Wie tief kann die Rekursion werden? Speicherbedarf durch den Aufrufstapel.
Wie wächst der Aufwand? Laufzeitbewertung aus Q1.2 bleibt relevant.
Welche Darstellung ist für Menschen besser lesbar? Iteration kann klarer sein, Rekursion kann die Struktur besser zeigen.

So schließt Q1.3 an Q1.2 an: Such- und Sortieralgorithmen bleiben vertraute Referenzpunkte, aber die Begründung wird tiefer. Es geht nicht nur um „funktioniert“ und „wie schnell“, sondern um die Frage, welche Struktur ein Problem hat und welche algorithmische Darstellung diese Struktur am besten sichtbar macht.