Professional Documents
Culture Documents
Rekurzija
Rekurzija
1
PROGRAMIRANJE II 2010/11.
REKURZIJA
2
PROGRAMIRANJE II 2010/11.
Primjer rekurzivnog postupka
Recimo, da idemo u trgovinu.
Možemo postupiti ovako:
Uzastopno koračamo u smjeru trgovine,
dok ne dođemo do nje.
Drugi način:
3
PROGRAMIRANJE II 2010/11.
Funkcija za postupak: idemoUTrgovinu()
void idemoUTrgovinu() {
if (u trgovini) obavljeno;
else {
napravi jedan korak prema trgovini;
idemoUTrgovinu()
}
}
rekurzivni poziv
4
PROGRAMIRANJE II 2010/11.
Rekurzija kao matematički pojam
6
PROGRAMIRANJE II 2010/11.
Rekurzivna funkcija
Rekurzivna funkcija – funkcija koja poziva
samu sebe
Rekurzija:
eksplicitna, direktna
implicitna, indirektna rekurzija
7
PROGRAMIRANJE II 2010/11.
Rekurzivna funkcija
8
PROGRAMIRANJE II 2010/11.
Primjer 1: Problem izračunavanja
faktorijele pozitivnog cijelog broja n
Iterativna definicija:
n! = 1 x 2 x 3 x ... x n, za n>=1
9
PROGRAMIRANJE II 2010/11.
#include<iostream.h>
unsigned long FAKT(int n);
void main(){
int n;
cout<<"Unesi prirodni broj: ";
cin>>n;
cout<<"\n"<<n<<"! = "<<FAKT(n)<<endl;
}
unsigned long FAKT(int n){
unsigned long fjel=1;
for(int i =2; i<=n; i++)
fjel*=i;
return fjel;
}
10
PROGRAMIRANJE II 2010/11.
Rekurzivno rješenje se temelji na
rekurzivnoj definiciji funkcije za
izračunavanje faktorijele:
0! = 1
n! = n x (n-1)!, za n=1,2,3,4,...
11
PROGRAMIRANJE II 2010/11.
#include<iostream.h>
unsigned long faktorijela(int n);
void main(){
int n;
unsigned long F;
cout<<"Unesi prirodni broj: ";
cin>>n;
F=faktorijela(n);
cout<<"\n"<<n<<"! = "<<F<<endl;
}
unsigned long faktorijela(int n){
long int f; // Ako riješavamo bez lokalne varijable
if (n==0 || n==1)f=1; // tada pišemo return 1
else // ovu liniju možemo izostaviti
f=n*faktorijela(n-1); // pišemo return n*faktorijela(n-1)
return f; // ovu liniju možemo isto izostaviti
} 12
PROGRAMIRANJE II 2010/11.
Rekurzivna izvedba računanja faktorijele [Šribar]
13
PROGRAMIRANJE II 2010/11.
UPORABA STOGA PRI POZIVU
POTPROGRAMA
xx
cc cc cc
bb bb bb
aa aa aa
15
PROGRAMIRANJE II 2010/11.
Primjer: Euklidov algoritam (izračunavanje
najvećeg zajedničkog djelitelja za dva cijela broja)
Rekurzivna funkcija:
int nzd(int x,int y)
{
if(y==0)return x;
return nzd(y,x%y);
}
16
PROGRAMIRANJE II 2010/11.
Prednosti i nedostaci rekurzije u
odnosu na iteraciju
Prednosti rekurzije:
Rekurzivno riješenje je često prirodnije (npr. izvedba
postupaka na rekurzivnim strukturama podataka).
Izvori nedostataka rekurzije:
Prostor koji rekurzija koristi na stogu proporcionalan je
dubini rekurzije (najveći stupanj gnježđenja funkcija u
rekurziji).
Rekurzija je i vremenski zahtjevna - iterativna rješenja
su obično učinkovitija.
Za rekurziju se odlučujemo kada je problem po
svojoj prirodi rekurzivan, a odgovarajuće
iterativno rješenje nije puno učinkovitije.
17
PROGRAMIRANJE II 2010/11.
Primjer neočekivanog rasta
zahtjevnosti problema
Prema legendi je pravila za šah izmislio indijski
mudrac Seta. Vladar Šeram mu je obećao za
nagradu pokloniti što god poželi.
Seta je za nagradu izabrao zrna pšenice, toliko
koliko je polja na šahovnici: na prvo polje 1 zrno,
na drugo 2 zrna, na treće 4 i na svako slijedeće
dva puta više nego na prethodno (za zadnje
polje 264 zrna).
•Vladar
18 446 744je 073
bio709
razočaran
551 615 zrna što Seta omalovažava
•njegovu velikodušnost,
1 200 000 000 000 m3 (u 1m3 idealipribližno
se neugodno iznenadio
15 milijuna zrna)
•kada
Ako je su njegovi
širina mudraci
silosa 10m, izračunali količinu zrnja,
a visina 4m:
koju duguje
silos ima duljinuSeti:
30 000 000 km
= 80x udaljenosti do Mjeseca ili petina udaljenosti od Zemlje do18
Sunca PROGRAMIRANJE II 2010/11.
Primjer: Problem hanojskih kula
Program:
#include <iostream.h>
void premjesti_kulu(int n,int sa,int
na,int pom);
void main(){
int n;
cout<<"\n Unesi broj diskova: ";
cin>>n;
premjesti_kulu(n,1,3,2);
cout<<endl;
}
void premjesti_kulu(int n,int sa,int na,int
pom){
if (n>0){
premjesti_kulu(n-1,sa,pom,na);
cout<<endl<<sa<<"-->"<<na;
premjesti_kulu(n-1,pom,na,sa);
} 20
PROGRAMIRANJE II 2010/11.
}
n=3
1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3
http://home.comcast.net/~asunnet/hanoi/
http://www.softschools.com/games/logic_games/tower_of_hanoi/
21
PROGRAMIRANJE II 2010/11.
Primjer 1: Inverzni ispis unesenog niza
znakova koji završava zvjezdicom (inverz.cpp)
22
PROGRAMIRANJE II 2010/11.
Primjer 2: Program s rekurzivnom funkcijom za
izračunavanje sume prirodnih brojeva od 1 do k
#include <iostream.h>
int suma(int n);
void main(){
int k;
cin>>k;
cout<<"\nSuma= "<<suma(k)<<endl;
}
24
PROGRAMIRANJE II 2010/11.
Primjer 4:
Napiši rekurzivnu funkciju koja na ulazu ima polje
sa elementima tipa double i veličinu polja, te
vraća zbroj elemenata polja.
25
PROGRAMIRANJE II 2010/11.
Primjer 5
Napiši rekurzivnu funkciju koja broji koliko ima
nula u nenegativnom broju.
brojiNule(10200) vraća 3
29
PROGRAMIRANJE II 2010/11.
Primjer sa kviza:
Što vraća poziv f(72,54)? Što računa funkcija?
31
PROGRAMIRANJE II 2010/11.
Napiši rekurzivnu funkciju koja računa
umnožak prirodnih brojeva od a do b (za
b>a).
32
PROGRAMIRANJE II 2010/11.
Preporuka za čitanje:
rekurzija.doc (prema Sedgewick, pogl.5)
33
PROGRAMIRANJE II 2010/11.