You are on page 1of 14

4.

Rekurzivne funkcije i procedure


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•(n1)!, 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( a1, b1 ) + Povrh( a1, 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
V1V2 ... 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, s1)
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
V1V2 ... 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).

Vremenska složenost MERGESORT jeste O( N log N )


Primjer rada MERGESORT-a
MergeSort(1,7)

MergeSort(1,4) MergeSort(5,7) s=(1+7)/2=4

s=(1+4)/2=2 MergeSort(1,2) MergeSort(3,4) MergeSort(5,6) MergeSort(7,7) s=(5+7)/2=6

MergeSort(1,1) MergeSort(3,3) MergeSort(5,5)


MergeSort(2,2) MergeSort(4,4) MergeSort(6,6)

MERGE(1,2) MERGE(3,4) MERGE(5,6)

MERGE(1,4) MERGE(5,7)

MERGE(1,7)

You might also like