rekurzija
TRANSCRIPT
TEORIJA ALGORITAMA I SUSTAVA
Predavanjadr. sc. Miroslav Slamić, prof. vis. šk.
VježbeNikola Majstorović, dipl. ing.
TEHNITEHNIČČKO VELEUKO VELEUČČILIILIŠŠTE U ZAGREBUTE U ZAGREBUSpecijalistiSpecijalističčki studij ki studij -- InformatikaInformatika
Rekurzija
3
Osnovna ideja
Procedura poziva samu sebeMora postojati završetak.
Pitanje:Zašto se dug napravljen kreditnom karticom ne može platiti istom kreditnom karticom?
Neki jezici (npr. stare verzije jezika FORTRAN) ne podržavaju rekurziju.Rekurzivni programi su kraći, ali izvođenje programa je dulje.Koristi se struktura podataka stog za pohranjivanje rezultata i povratak iz rekurzije.
4
Karakteristike rekurzijeOsnovni slučajevi: uvijek moraju postojati osnovni slučajevi koji se rješavaju bez rekurzijeNapredovanje: Za slučajeve koji se rješavaju rekurzivno, svaki sljedeći rekurzivni poziv mora se približiti osnovnim slučajevima.Pravilo projektiranja: Podrazumijeva se da svaki rekurzivni poziv funkcionira.Pravilo ne ponavljanja: Ne valja dopustiti da se isti problem rješava odvojenim rekurzivnim pozivima. (To rezultira umnažanjem posla, vidi npr. Fibonaccijevibrojevi).
Primjer za pogreškuint los (int n) {
if (n == 0) return 0;return los (n / 3 + 1) + n - 1;
}Pogreška jest u tome što za vrijednost n = 1 rekurzivni poziv je opet s argumentom 1. Nema znači napredovanja prema osnovnom slučaju. Program međutim ne radi niti za druge vrijednosti argumenta. Npr. za n = 4, rekurzivno se poziva los s argumentom4/3 +1 = 2, zatim 2/3 +1 = 1 i dalje stalno 1/3 +1 = 1.
55
ElementarnaElementarna rekurzijarekurzija i i sistemski sistemski stogstogElementarnaRekurzijaElementarnaRekurzija
void f(int i){
f’’
f(i+1);int v;
return;}
void f(int i){
f’’’
f(i+1);int v;
return;}
void f(int i){
f(i+1);int v;
return;}
f’
...
...f(1);
STOG
void f(int i){
f
f(i+1);int v;
return;}
1p.a.BPv
1p.a.BPv2
p.a.BPv
1p.a.BPv2
p.a.BPv3
p.a.BPv
1p.a.BPv2
p.a.BPv3
p.a.BPv4
p.a.BPv
...
66
IzraIzraččunavanje unavanje faktorijelafaktorijelaJedan od jednostavnih rekurzivnih algoritama jest izraJedan od jednostavnih rekurzivnih algoritama jest izraččunavanje unavanje n!n! zaza n >= n >= 00..
00! = ! = 1111! = ! = 11n! = n* (nn! = n* (n--1)!1)!int fakt(int n){int fakt(int n){
ifif (n <= 1) {(n <= 1) {
returnreturn 1;1;
} } elseelse {{
returnreturn n * fakt(nn * fakt(n--1);1);
}}
}}
Primjer: 4!Primjer: 4!k = fakt (4);k = fakt (4);
= 4 * fakt (3);= 4 * fakt (3);
= 3 * fakt (2);= 3 * fakt (2);
= 2 * fakt (1);= 2 * fakt (1);
= 1 = 1
77
IzraIzraččunavanje unavanje faktorijelafaktorijela
...
...i=fakt(3);
STOG (n)3
int fakt(int n){
fakt
return 1;
if (n <= 1) {
} else {
return n*fakt(n-1);
}
}
int fakt(int n){
fakt’
return 1;
if (n <= 1) {
} else {
return n*fakt(n-1);
}
}
int fakt(int n){
fakt’’
return 1;
if (n <= 1) {
} else {
return n*fakt(n-1);
}
}
32
321
16 2
Faktorijeli
88
PrimjerPrimjer : : FaktorijelFaktorijel
Faktorijel(4)
Faktorijel(3)4 ×
Faktorijel(2)3 ×
Faktorijel(1)2 ×
1
99
PrimjerPrimjer : : FaktorijelFaktorijel
Faktorijel(4)
Faktorijel(3)4 ×
Faktorijel(2)3 ×
Faktorijel(1)2 ×
1
1010
PrimjerPrimjer : : FaktorijelFaktorijel
Faktorijel(4)
Faktorijel(3)4 ×
Faktorijel(2)3 ×
12 ×
1111
PrimjerPrimjer : : FaktorijelFaktorijel
Faktorijel(4)
Faktorijel(3)4 ×
Faktorijel(2)3 ×
12 ×
1212
PrimjerPrimjer : : FaktorijelFaktorijel
Faktorijel(4)
Faktorijel(3)4 ×
23 ×
1313
PrimjerPrimjer : : FaktorijelFaktorijel
Faktorijel(4)
Faktorijel(3)4 ×
23 ×
1414
PrimjerPrimjer : : FaktorijelFaktorijel
Faktorijel(4)
64 ×
1515
PrimjerPrimjer : : FaktorijelFaktorijel
Faktorijel(4)
64 ×
1616
PrimjerPrimjer : : FaktorijelFaktorijel
24
1717
Zadaci za vjeZadaci za vježžbubu
Napisati funkciju koja prima dva argumenta Napisati funkciju koja prima dva argumenta x i i y, cjelobrojnog tipa, i vra, cjelobrojnog tipa, i vraćća preko imena a preko imena vrijednost vrijednost xy..
PotencijaRekurzijomPotencijaRekurzijom
Poziv funkcije:Poziv funkcije:k = pot(2,5);
= 2*pot(2,4)= 2*pot(2,3)
= 2*pot(2,2)= 2*pot(2,1)
= 2*pot(2,0)= 1
1818
SadrSadržžaj stogaaj stoga
potpot(2,5)(2,5) potpot(2,4)(2,4) potpot(2,3)(2,3) potpot(2,2)(2,2) potpot(2,1)(2,1) potpot(2,0)(2,0) returnreturn11
returnreturn2*12*1
returnreturn2*22*2
returnreturn2*42*4
returnreturn2*82*8
returnreturn2*162*16
(2,0)(2,0) 11
(2,1)(2,1) (2,1)(2,1) (2,1)(2,1) 22
(2,2)(2,2) (2,2)(2,2) (2,2)(2,2) (2,2)(2,2) (2,2)(2,2) 44
(2,3)(2,3) (2,3)(2,3) (2,3)(2,3) (2,3)(2,3) (2,3)(2,3) (2,3)(2,3) (2,3)(2,3) 88
(2,4)(2,4) (2,4)(2,4) (2,4)(2,4) (2,4)(2,4) (2,4)(2,4) (2,4)(2,4) (2,4)(2,4) (2,4)(2,4) (2,4)(2,4) 1616
(2,5)(2,5) (2,5)(2,5) (2,5)(2,5) (2,5)(2,5) (2,5)(2,5) (2,5)(2,5) (2,5)(2,5) (2,5)(2,5) (2,5)(2,5) (2,5)(2,5) (2,5)(2,5) 3232
1919
Zadaci za vjeZadaci za vježžbubu
ŠŠto bi se dogodilo kada bi bila izostavljena linija:to bi se dogodilo kada bi bila izostavljena linija:ifif (y <= 0) (y <= 0) returnreturn 1;1;Funkcija bi samu sebe pozivala beskonaFunkcija bi samu sebe pozivala beskonaččno puta i nikada ne bi vratila neku no puta i nikada ne bi vratila neku vrijednost u glavni program. vrijednost u glavni program. NprNpr. u gornjem primjeru dogodilo bi se slijede. u gornjem primjeru dogodilo bi se slijedećće:e:
pot(2,5);= 2*pot(2,4)
= 2*pot(2,3)= 2*pot(2,2)
= 2*pot(2,1)= 2*pot(2,0)
= 2*pot(2,-1)= 2*pot(2,-2)
= 2*pot(2,-3)...
2020
Zadaci za vjeZadaci za vježžbubu
RjeRješšenje bez enje bez rekurzijerekurzije::int pot(long x, long y) {
int retval = 1;int i;
for (i = 0; i < y; i++) retval *= x;
return retval;}
Napisati funkcije koja ispisuju sve brojeve do ili od n na razneNapisati funkcije koja ispisuju sve brojeve do ili od n na razne nanaččine.ine.RekurzivniIspisRedom
Napisati rekurzivnu funkciju koja raNapisati rekurzivnu funkciju koja raččuna nuna n--ti ti ččlan aritmetilan aritmetiččkog niza.kog niza.AritmetickiNizNiz
2121
LeonardoLeonardo Pisano Pisano FibonacciFibonacci
RođenRođen: 1170 (vjerojatno) : 1170 (vjerojatno) PisaPisaUmro: 1250 (vjerojatno) Umro: 1250 (vjerojatno) PisaPisa
Godine 1202Godine 1202 LiberLiber abaciabaci : :
Uvođenje Uvođenje hinduhindu--arapskih brojevaarapskih brojevaSimultane linearne jednadSimultane linearne jednadžžbebeTrgovaTrgovaččki matematiki matematiččki problemiki problemiIzraIzraččun profitaun profitaPreraPreraččun valutaun valuta
2222
Arapski brojeviArapski brojevi
٠٠ 0 0 SiferSifer١١ 1 1 WahidWahid٢٢ 2 2 IthininIthinin٣٣ 3 3 ThalathaThalatha٤٤ 4 4 ArbaArba'a'a٥٥ 5 5 KamisaKamisa٦٦ 6 6 SitaSita٧٧ 7 7 SabaSaba'a'a٨٨ 8 8 ThamaniaThamania٩٩ 9 9 Tisa'aTisa'a١١ ٠٠ 10 10 AsharaAshara
Ne poklapaju se s naNe poklapaju se s naššim im ““arapskimarapskim”” brojevima.brojevima.NajveNajvećće dostignue dostignućće e –– uvođenje nule i te uvođenje nule i težžinskih mjesta.inskih mjesta.
2323
FibonaccijeviFibonaccijevi brojevibrojevi
1,1,2,3,5,8,13,21,34,... (koji je sljede1,1,2,3,5,8,13,21,34,... (koji je sljedećći?)i?)
FF00=F=F11==11FFii==FFii--22++FFii--11; i>; i>11
int F(int n) {int F(int n) {
ifif (n <= 1) (n <= 1)
returnreturn 1;1;
elseelse
returnreturn F(nF(n--2) + F(n2) + F(n--1);1);
}}
Program je vrlo kratak i potpuno odgovara matematiProgram je vrlo kratak i potpuno odgovara matematiččkoj definiciji. Efikasnost je vrlo koj definiciji. Efikasnost je vrlo niska.niska.
24
Primjer: Fibonacci
Fibonacci serija se definira rekurzivno na sljedeći način:
Fibonacci(0) = 0
Fibonacci(1) = 1
Fibonacci(n) = Fibonacci(n - 2) + Fibonacci(n - 1)
25
/* Compute the n-th Fibonacci number, when=0,1,2,... */
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
function Fibonacci ( n ){
if ( n is less than or equal to 1 ) thenreturn n
elsereturn Fibonacci ( n - 2 ) + Fibonacci ( n - 1 )
}
Primjer: fibonacc.c
26
Primjer: Računanje fib(4)
+fib(2) fib(3)
fib(4)
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
4
4
4 4
27
Primjer: Računanje fib(4)
fib(2) fib(3)+
fib(4)
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
2
2
2 2
+fib(0) fib(1)
28
Primjer: Računanje fib(4)
fib(2) fib(3)+
fib(4)
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
0
0
+fib(0) fib(1)
0
29
Primjer: Računanje fib(4)
fib(2) fib(3)+
fib(4)
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
0
0
+0 fib(1)
0
30
Primjer: Računanje fib(4)
fib(2) fib(3)+
fib(4)
+ fib(1)0
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
2
2
220
31
Primjer: Računanje fib(4)
fib(2) fib(3)+
fib(4)
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
1
1
+ fib(1)0
1
32
Primjer: Računanje fib(4)
fib(2) fib(3)+
fib(4)
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
1
1
+ 10
1
33
Primjer: Računanje fib(4)
fib(2) fib(3)+
fib(4)
+0 1
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
2
2
0 21
34
Primjer: Računanje fib(4)
1 fib(3)+
fib(4)
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
2
2
0
+0 1
21
35
Primjer: Računanje fib(4)
+ fib(3)
fib(4)
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
4
4
4 4
1
+0 1
1
36
Primjer: Računanje fib(4)
+ fib(3)
fib(4)
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
3
3
3 3
1
+0 1 +fib(1) fib(2)
37
Primjer: Računanje fib(4)
+ fib(3)
fib(4)
1
+0 1 +fib(1) fib(2)
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
1
11
38
Primjer: Računanje fib(4)
+ fib(3)
fib(4)
1
+0 1 +1 fib(2)
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
1
11
39
Primjer: Računanje fib(4)
+ fib(3)
fib(4)
1
+0 1 +1 fib(2)
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
3
3
3 31
40
Primjer: Računanje fib(4)
+ fib(3)
fib(4)
1
+0 1 +1 fib(2)
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
2
2
2 2
+fib(0) fib(1)
41
Primjer: Računanje fib(4)
+ fib(3)
fib(4)
1
+0 1 +1 fib(2)
+fib(0) fib(1)
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
0
00
42
Primjer: Računanje fib(4)
+ fib(3)
fib(4)
1
+0 1 +1 fib(2)
+0 fib(1)
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
0
00
43
Primjer: Računanje fib(4)
+ fib(3)
fib(4)
1
+0 1 +1 fib(2)
+0 fib(1)
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
2
2
2 20
44
Primjer: Računanje fib(4)
+ fib(3)
fib(4)
1
+0 1 +1 fib(2)
+0 fib(1)
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
1
11
45
Primjer: Računanje fib(4)
+ fib(3)
fib(4)
1
+0 1 +1 fib(2)
+0 1
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
1
11
46
Primjer: Računanje fib(4)
+ fib(3)
fib(4)
1
+0 1 +1 fib(2)
+0 1
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
2
2
2 20 1
47
Primjer: Računanje fib(4)
+ fib(3)
fib(4)
1
+0 1 +1 1
+0 1
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
2
2
2 20 1
48
Primjer: Računanje fib(4)
+ fib(3)
fib(4)
1
+0 1 +1 1
+0 1
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
3
3
3 31 1
49
Primjer: Računanje fib(4)
+ 2
fib(4)
1
+0 1 +1 1
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
3
3
3 31 1
+0 1
50
Primjer: Računanje fib(4)
+ 2
fib(4)
1
+0 1 +1 1
+0 1
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
4
4
4 41 2
51
Primjer: Računanje fib(4)
+ 2
3
1
+0 1 +1 1
+0 1
long fib ( long n ){
if ( n <= 1 )return n ;
elsereturn fib( n - 2 ) + fib( n - 1 );
}
4
4
4 41 2
52
Primjer: Računanje fib(4)
+ 2
3
1
+0 1 +1 1
+0 1
Dakle, fib(4) vraća vrijednost 3.