Rekurencja
Definicja rekurencji: 1. Zakończenie algorytmu jest jasno określone; 2. „Duży” problem = problem elementarny + problem o mniejszym stopniu skomplikowania niż problem początkowy.
Zadanie: dysponujesz tablicą n liczb całkowitych; należy określić, czy w tablicy występuje liczba x podana jako parametr? Algorytm rekurencyjny rozwiązania: Pobierz pierwszy niezbadany element tablicy n-elementowej; Jeśli ten element jest równy x, to wypisz “element znaleziono” i zakończ zadanie; W przeciwnym przypadku zbadaj pozostałą część tablicy.
Podstawowe błędy w programach rekurencyjnych: złe określenie warunku zakończenia programu; niewłaściwa dekompozycja problemu.
Jak wykonują się programy rekurencyjne? Przykład: Napisz program rekurencyjny na obliczenie silni z n: 0! = 1; n! = n*(n-1)!, dla n >= 1
Silnia: Obliczenia silnia(5) = 5*silnia(4) = 5*(4*silnia(3)) = 5*(4*(3*(2*(1*1)))) = 5*(4*(3*(2*1))) = 5*(4*(3*2)) = 5*(4*6) = 5*24 = 120
Niebezpieczeństwa rekurencji: nieskończona liczba wywołań rekurencyjnych; wielokrotne wykonanie identycznych obliczeń; przepełnienie stosu;
Ciąg Fibonacciego: fib(0) = 1, fib(1) = 1, fib(n) = fib(n-1) + fib(n-2), gdzie n 2. Zadanie polega na napisaniu programu generującego elementy ciągu Fibonacciego. Ciąg Fibonacciego jest używany do wielu różnych i czsami zaskakujących celów. Program FIB.CPP generuje liczby Fibonacciego. Spróbujmy prześledzić dokładnie wywołania rekurencyjne dla n = 4. Nieskomplikowana analiza prowadzi do następującego drzewa przedstawionego na rysunku poniżej:
Wywołania rekurencyjne funkcji Fibonacciego dla n = 4 Każdy zacieniowany prostokąt symbolizuje problem elementarny, natomiast problem o rozmiarze n 2 zostaje rozbity na dwa problemy o mniejszym stopniu skomplikowania: n-1 i n-2. Można łatwo dostrzec, że znaczna część obliczeń jest wykonywana wielokrotnie, np. cała gałąź zaczynająca się od fib(2) jest zdublowana. Funkcja Fib nie ma żadnej możliwości, aby to zauważyć. (Patrz program FIB.CPP). fib(0) = 1, fib(1) = 1, fib(n) = fib(n-1) + fib(n-2), gdzie n 2.