Funkcja jest rekurencyjna, gdy wywołuje samą siebie w celu rozwiązania mniejszej wersji tego samego problemu. Każda poprawna funkcja rekurencyjna musi mieć dwa elementy:
Jeśli funkcja rekurencyjna nigdy nie osiąga przypadku bazowego, program zgłosi błąd RecursionError: maximum recursion depth exceeded. To najczęstszy błąd początkujących.
Każde wywołanie funkcji odkłada na stos wywołań nową "ramkę", która czeka, aż wywołanie zagnieżdżone zwróci wynik:
| Kryterium | Rekurencja | Iteracja |
|---|---|---|
| Czytelność dla problemów "z natury rekurencyjnych" | Zwykle wyższa (drzewa, fraktale, przeszukiwanie grafów) | Może wymagać dodatkowych struktur (np. własnego stosu) |
| Zużycie pamięci | Wyższe — każde wywołanie zajmuje ramkę na stosie | Stałe — jedna zmienna licznika |
| Ryzyko błędu | Przepełnienie stosu przy braku/złym warunku stopu | Pętla nieskończona przy błędnym warunku |
| Szybkość | Zwykle wolniejsza (narzut wywołań funkcji) | Zwykle szybsza |
Fraktal to figura, której fragment wygląda podobnie do całości — idealny przykład zastosowania rekurencji. Klasyczny przykład: drzewo fraktalne — gałąź rozgałęzia się na dwie mniejsze gałęzie, każda z nich znowu na dwie, aż do osiągnięcia minimalnej długości (warunek stopu).
Trójkąt Sierpińskiego — trójkąt dzielony rekurencyjnie na 3 mniejsze trójkąty w narożnikach. Płatek Kocha — każdy odcinek zastępowany łamaną w kształcie "ząbka". Oba budowane są dokładnie tą samą techniką: funkcja rekurencyjna z warunkiem stopu opartym na głębokości rekursji lub minimalnym rozmiarze.
Napisz funkcję rekurencyjną fib(n) zwracającą n-ty wyraz ciągu Fibonacciego (fib(0)=0, fib(1)=1, fib(n)=fib(n-1)+fib(n-2)). Następnie odpowiedz: dlaczego dla n=35 program zauważalnie zwalnia?
Ta wersja ma złożoność O(2ⁿ) — te same podproblemy (np. fib(30)) liczone są wielokrotnie, bo funkcja nie zapamiętuje wcześniej obliczonych wyników. To problem, który rozwiążemy metodą programowania dynamicznego w Bloku 15.
Napisz funkcję suma_cyfr(n), która rekurencyjnie sumuje cyfry liczby naturalnej n (np. suma_cyfr(1234) = 10).
1. Co się stanie, jeśli funkcja rekurencyjna nie ma poprawnego warunku stopu?
2. Co jest odkładane na stos wywołań przy każdym wywołaniu funkcji rekurencyjnej?
3. Co czyni figurę fraktalem?