Professional Documents
Culture Documents
SEMINARSKI RAD
SEMINARSKI RAD
STUDENT:
PREDMET: Strukture podataka i algoritmi
PROFESOR: Mahir Zajmović
ASISTENT: Potpis studenta:________________
1 UVOD.....................................................................................................................................1
1.1 Problem, predmet i objekat istraživanja..........................................................................2
1.2 Svrha i ciljevi istraživanja................................................................................................2
1.3 Struktura rada..................................................................................................................2
1.4 Metode rada....................................................................................................................2
2 POJAM REKURZIJE..............................................................................................................3
3 VRSTE i primjeri rekurzivnih funkcija.....................................................................................6
3.1 Faktorijel..........................................................................................................................6
3.2 Sumiranje niza.................................................................................................................6
3.3 Stepenovanje..................................................................................................................7
3.4 Fibonačijev niz.................................................................................................................8
3.5 NZD (Euklidov algoritam)................................................................................................9
3.6 Hanojske kule (kule Hanoja)...........................................................................................9
3.7 Uzajamna rekurzija.......................................................................................................10
4 DOBRE I LOŠE STRANE REKURZIJE...............................................................................11
5 ZAKLJUČAK.........................................................................................................................13
6 LITERATURA.......................................................................................................................14
1 UVOD
Kod rekurzivnih algoritama problem možemo riješiti kroz jednu funkciju koja višestruko
poziva samu sebe dok ne postigne osnovno rješenje ili kroz više funkcija koje se višestruko
međusobno pozivaju po istom principu rješavanja rekurzije. Algoritam možemo rješavati
primjenom rekurzije samo u slučaju da algoritam ima završetak, u protivnom se algoritam očito
ne može riješiti ni rekurzivnim ni drugim postupkom. S obzirom da za implementaciju rekurzije
koristimo funkcije, za svaki poziv funkcije mora se koristiti sistemski stog (stackframe) za
čuvanje vrijednosti lokalnih varijabli funkcije i povratne adrese pozivnog programa. Kako je
veličina sistemskog stoga ograničena i definirana kompajlerom to može biti ograničavajući
faktor za primjenu rekurzije.
1.1 Problem, predmet i objekat istraživanja
Kao predmet istraživanja ovaj rad razmatra pojam rekurzije, vrste rekurzivnih funkcija, primjenu
rekurzije, te prednosti i nedostatke.
Ovaj rad ima za cilj razmotriti na koji način se rekurzija primjenjuje u programiranju te da se na
taj način uvidi značaj primjene korištenja rekurzije nekog osnovnog algoritma.
Rad se sastoji od pet osnovnih cjelina: uvod, definiranje pojma rekurzije, vrste i primjeri
rekurzivnih funkcija, dobre i loše strane rekurzije, te zaključak.
Centralni dio rada ima za cilj da pobliže definira pojam rekurzivne funkcije, ta da objasni koje su
to vrste rekurzivnog algoritma kao i njegovu primjenu u praksi.
Kao metoda istraživanja koristit će se opis metoda rekurzivne funkcije, različite vrste primjene
rekurzije koje se koriste u programiranju, te njene prednosti i nedostaci.
2
2 POJAM REKURZIJE
F(n) = F(n-1)+F(n-2).
Ovaj izraz znači da se n-ti fibonačijev broj izračunava kao zbir n-1-og i n-2-og
fibonačijevog broja, koji se opet izračunavaju na isti način kao n-ti broj.
Drugi način definisanja rekurzije kaže da rekurzija predstavlja način definisanja problema
preko pojednostavljene verzije istog tog problema. Jedan primjer kojim se ovo može opisati je
rješavanje problema pronalaska puta do kuće (problem ćemo označiti izrazom “pronađi put do
kuće”). Rekurzijom bi se ovaj problem mogao opisati u tri koraka, na sledeći način:
Tačka pod brojem 3 u ovom opisu problema predstavlja poziv istog problema iz definicije,
ali posle učinjene jedne jednostavne akcije, a to je jedan korak prema kući, problem je
pojednostavljen.
Opisani postupak se može uopštiti, čime dobijamo generalni algoritam koji rješava probleme
rekurzijom, i on se sastoji od sledeća tri koraka:
3. rekurzivni poziv.
Ovako opisani postupak rješavanja problema ima algoritamski oblik i za većinu problema se
može implementirati.
3
U matematici i informatici, rekurzija je pristup u kojem se neki pojam, objekat ili funkcija
definiše na osnovu jednog ili više baznih slučajeva i na osnovu pravila koja složene slučajeve
svode na jednostavnije.
Rekurzija se implementira preko funkcija i predstavlja pojavu u kojoj funkcija poziva samu
sebe. Korištenjem rekurzije moguće je simulirati rad petlje, odnosno ponavljanja bloka naredbi.
Rekurzija se često koristi u rješavanju raznih matematičkih problema, kao što su izračunavanje
faktorijela nekog broja, fibonačijevih brojeva i sl, ali se koristi i u programerskim zadacima kao
što su sortiranje nizova, pretraživanje složenih struktura podataka i rješavanje složenih
programerskih problema (na primjer raspored kraljica na šahovskoj tabli).
void recursion() {
...
recursion(); /* funkcija poziva samu sebe */
...
}
int main() {
recursion(); /* poziv rekurzivne funkcije */
int main()
{
int n = 6;
int rez = suma(6);
printf("Suma prvih %d brojeva je %d \n", n, rez);
return 0;
}
4
int suma(int n){
int rez;
rez = n + suma(n-1);
return rez;
}
int main()
{
int n = 6;
int rez = suma(6);
printf("Suma prvih %d brojeva je %d \n", n, rez);
return 0;
}
Pored klasične rekurzije o kojoj je do sada bilo riječi postoji i takozvana uzajamna ili
indirektna rekurzija koja se odnosi na situaciju kada dvije funkcije jedna drugu pozivaju
rekurzivno. Na ovaj način funkcija ne poziva samu sebe direktno, nego posredno preko druge
funkcije. Ova situacija se može opisati sledećim programskim kodom:
void funkcijaA(){
...
funkcijaB();
...
}
void funkcijaB(){
...
funkcijaA();
....
5
}
U programiranju, rekurzija je tehnika u kojoj funkcija poziva samu sebe, direktno ili
indirektno. Rekurzivne funkcije su pogodne za širok spektar informatičkih problema, ali
pored svojih dobrih strana imaju i loše.
3.1 Faktorijel
Funkcija faktorijel (za prirodni broj 𝑛, vrijednost 𝑛! jednaka je proizvodu svih prirodnih
brojeva od 1 do 𝑛) može se definisati na (primitivno) rekurzivan način:
- 0! = 1 (bazni slučaj)
- za 𝑛 > 0 važi: 𝑛! = 𝑛 · (𝑛 − 1)! (rekurzivni korak)
unsigned faktorijel(unsigned n) {
if (n == 0)
return 1;
else
return n*faktorijel(n-1);
Rekurzivna funkcija koja sumira elemente niza može se definisati na sljedeći način:
6
float suma(float a[], unsigned n) {
if (n == 0)
return 0.0f;
else
3.3 Stepenovanje
if (k == 0)
return 1.0f;
else
m *= x;
7
return m;
if (k == 0)
return 1.0f;
else if (k % 2 == 0)
else
unsigned fib(unsigned n) {
if (n == 0 || n == 1)
return n;
else
8
3.5 NZD (Euklidov algoritam)
Euklidov algoritam za izračunavanje najvećeg zajedničkog djelioca dva broja se može izračunati
narednom rekurzivnom funkcijom, pretpostavlja se da je a ≥ b.
if (b == 0)
return a;
else
Problem kula Hanoja glasi ovako: date su tri kule i na prvoj od njih 𝑛 diskova opadajuće
veličine; zadatak je prebaciti sve diskove sa prve na treću kulu (koristeći i drugu) ali tako da
nikada nijedan disk ne stoji iznad manjeg.
if (n > 0) {
9
kule(n-1, pomocna, dolazna, polazna);
}
}
int paran(int n) {
if (n==0)
return 1;
else
return neparan(n-1);
int neparan(int n) {
if (n==0)
return 0;
else
return paran(n-1);
10
4 DOBRE I LOŠE STRANE REKURZIJE
Cijena poziva. Prilikom svakog rekurzivnog poziva kreira se novi stek okvir i kopiraju se
argumenti funkcije. Kada rekurzivnih poziva ima mnogo, ovo može biti veoma memorijski i
vremenski zahtjevno, te je poželjno rekurzivno rješenje zamijeniti iterativnim.
unsigned memo[MAX_FIB];
unsigned fib(unsigned n) {
if (n == 0 || n == 1)
return memo[n] = n;
else
11
}
Na primjer, gore navedena funkcija fib može se zamijeniti iterativnom funkcijom koja od
početnih elemenata niza postepeno sintetiše sve dalje i dalje elemente niza. Primijetimo da za
izračunavanje 𝑛-tog elementa niza nije neophodno pamtiti sve elemente niza do indeksa n već
samo dva prethodna:
int fib(int n) {
if (n == 0 || n == 1)
return n;
fpp = 0;
fp = 1;
fpp = fp;
fp = f;
return fp;
12
5 ZAKLJUČAK
Rekurzija je funkcija koja poziva sama sebe. Rekurzivno programiranje je često korištena
tehnika kojom je moguće implementirati razne algoritme. Rekurzija uvijek mora imati neko
ograničenje koje će je zaustaviti, jer bi se u suprotnom funkcija pozivala beskonačan broj puta, i
program se nikada ne bi izvršio.
Rekurzija program čini elegantnim. Međutim, ako su performanse vitalne, umjesto toga bolje je
koristiti petlje jer je rekurzija obično puno sporija. Rekurzija je važan pojam, pomaže u
rješavanju problema i često se koristi u strukturi podataka i algoritmima. Na primjer, uobičajeno
je koristiti rekurziju u problemima kao što je prelazak stabla, putopisi, razvrstavanje i
pretraživanje i može se učinkovito koristiti gdje god je potrebno.
13
6 LITERATURA
Janičić, P. & Marić, F., 2017. Programiranje 2. Beograd: Matematički fakultet univerziteta u
Beogradu.
Manger, R. & Marušić, M., 2003. STRUKTURE PODATAKA I ALGORITMI. Zagreb: Sveučilište u
Zagrebu.
Živković, D., 2010. Uvod u algoritme i strukture podataka. Beograd: Univerzitet Singidunum.
14