rekurzija

27
TEORIJA ALGORITAMA I SUSTAVA Predavanja dr. sc. Miroslav Slamić, prof. vis. šk. Vježbe Nikola Majstorović, dipl. ing. TEHNI TEHNIČKO VELEU KO VELEUČILI ILIŠTE U ZAGREBU TE U ZAGREBU Specijalisti Specijalistički studij ki studij - Informatika Informatika Rekurzija

Upload: klompsjr

Post on 10-Oct-2014

100 views

Category:

Documents


1 download

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.

53

int main(void){

long broj;

printf(“Unesi broj: ");scanf("%ld", &number);

printf("Fibonacci(%ld) = %ld\n", broj, fib(broj));

return 0;}

Primjer: fibonacc.c

Primjer za main() za testiranje fib() funkcije: