Rekurzivna funkcija ili procedura – ona koja poziva samu sebe unutar svojih naredbi barem jednom (može i više puta). Primjerice, za n faktorijela vrijedi rekurzivna formula n! = n•(n1)!, 0!=1
Algoritam rekurzivne funkcije NFAKT( n )
Ako je n=0 onda vratiti 1 vratiti n * NFAKT( n 1 )
Zbog ovog poziva je rekurzivna!
Primjer rekurzivne procedure Rekurzivne procedure ne vraćaju nikakvu vrijednost ali rade na rekurzivan način.
Algoritam rekurzivne procedure d2b( n )
Ako je n=0 onda završi proceduru d2b( ⌊n/2⌋) Ispiši n mod 2
Koliko iznosi d2b( 26 )?
Što zapravo radi d2b(n) procedura? Pisanje rekurzivnih funkcija OPREZ! Kod pisanja rekurzivnih funkcija ili procedura možemo dovesti u pitanje konačnost algoritma!
PRAVILA za pisanje: Uvijek mora postojati neki ‘nerekurzivni put’ izlaska iz takve funkcije, to su trivijalni slučajevi za ulazne parametre funkcije.
Općenito rekurzivna procedura ima oblik:
Ako je rješenje trivialno vratiti to rješenje
U suprotnom obaviti rekurzivni poziv Podrška rekurzivnosti Skoro svi programski jezici podržavaju mogućnost da funkcije ili procedure pozivaju same sebe.
Ipak može postojati slučaj (nekih starijih, ili manje
razvijanih) programskih jezika koji ne podržavaju rekurzije.
Ukoliko ne podržavaju rekurzije, onda je moguće
izvesti strukturu STOGA, a postoji bliska veza između rekurzivnih funkcija ili procedura i stoga. Veza između rekurzivnih funkcija i stoga Postoji vrlo bliska veza:
“Skoro svaki algoritam koji je moguće napisati kao
rekurzivnu funkciju ili proceduru, moguće ga je napisati bez korištenja rekurzije, vrlo često upotrebom stoga”
Vrijedi i obrnuto:
“Skoro svaki algoritam koji koristi stog, moguće je
napisati kao rekurivnu funkciju ili proceduru” Problem računanja ‘povrh’ (rekurzija) ZADANO: Nenegativni brojevi a,b; a≥b a TRAŽI SE: () Dati rekurzivnu funkciju koji će vratiti b
Iskorištavamo potpuno istu ideju kao kod rješenja sa stogom.
Algoritam funkcije Povrh( a, b )
Ako je a = b ili b = 0 onda Vratiti 1 Vratiti Povrh( a1, b1 ) + Povrh( a1, b ) Rekurzivna funkcija vs korištenje stoga
Na prethodnom primjeru vidjeli smo rješenje problema ‘povrh’
koristeći rekurziju, a još prije smo vidjeli algoritam koji koristi stog.
Možemo zaključiti ono što vrijedi i općenito:
-Rekurzivna funkcija je obično manja u svom algoritamskom zapisu, ne treba definiranje nikakvih dodatnih funkcija (kao što su push, pop,... kod stoga) -Stog ima prednost da se algoritmi koji ga koriste ipak brže izvršavaju na računalu od njima ekvivalentnog rekurzivnog algoritma, osim toga lakše je razumjeti i analizirati takve algoritme, jer kod rekurzivnih funkcija zna biti znatno komplicirana analiza, pogotovo kada imamo više rekurzivnih poziva. QUICKSORT rekurzijom (1/2) ZADANO: Niz V od N elemenata TRAŽI SE: Preurediti elemente niza tako da bude V1V2 ... VN
Algoritam QUICKSORT REKURZIJOM
Pozvati proceduru QuickSort(1, N )
Algoritam procedure QuickSort( dg, gg )
Ako je dg gg završiti proceduru s = Nadji_s( dg, gg ) /* funkcija Nadji_s je ista kao prije */ QuickSort( dg, s1) QuickSort( s+1, gg ) QUICKSORT rekurzijom (2/2)
Vremenska složenost izvođenja ista je i u ovom
rekurzivnom rješenju, ali ju je puno teže odrediti jer na prvi pogled ne vidimo nikakvo ponavljanje (petlje).
Ako usporedimo rješenje koje koristi stog za spremanje
donje i gornje granice i u ovom slučaju vidimo da je puno jednostavniji rekurzivni zapis. MERGESORT (1/4) Promatrajmo opet problem sortiranja: ZADANO: Niz V od N elemenata TRAŽI SE: Preurediti elemente niza tako da bude V1V2 ... VN
- uvijek prepoloviti zadani niz, ponavljati
polovljenje sve dok ne dođemo do jedinične veličine, spajati dvije sortirane polovice u jednu sortiranu cjelinu MERGESORT (2/4) Algoritam MERGESORT REKURZIJOM MergeSort( 1, N )
Algoritam procedure MergeSort( dg, gg )
Ako je dg=gg završi proceduru s=(dg+gg)/2 MergeSort( dg, s ) MergeSort( s+1, gg ) MERGE( dg, gg ) MERGESORT (3/4) Algoritam procedure MERGE ( dg, gg ) Dodatno koristimo još jedan niz T duljine gg–dg+1 s=(dg+gg)/2, il = dg, id = s+1 Za svaki i=1 do gg–dg+1 činiti Ako je il s i id gg onda Ako je Vil < Vid onda Ti = Vil , il = il + 1 U suprotnom Ti = Vid , id = id + 1 U suprotnom Ako je il > s onda Ti = Vid , id = id + 1 U suprotnom Ti = Vil , il = il + 1 Za svaki i = dg do gg činiti Vi = Ti–dg MERGESORT (4/4) Spajanje podnizova (procedura MERGE) izvršava se u linearnom vremenu!
Međutim, zbog rekurzivnih poziva, originalni niz od N
elemenata se razbija na log2N razina.
Ukupni broj elemenata koje treba spajati u svakoj od
razina je najviše N (ma koliko ta razina imala podnizova).