Sunteți pe pagina 1din 28

Curs 6 - agenda

LLin - implementare:
cu tablouri; cu liste simplu nlnuite.

Recursivitate. Exemple

Algoritmi i programare

LLin: implementare cu tablouri


L = (e0,, en-1)

Elt[MAX]

e0
0

en-1 nrElt-1 MAX-1

Algoritmi i programare

Fiierul elt.h
#ifndef _ELT_H #define _ELT_H typedef int Elt; #endif

Algoritmi i programare

Fiierul llin.h
#include "elt.h" #define #define #define #define MAX_LLIN 1000 SUCCES 0 ERR_LLIN_MEM_INSUF 1 ERR_LLIN_INDEX_GRESIT 2

struct LLin { Elt tab[]; int nrElt; };


int listaVida(LLin *l); // declaratiile prototipurilor functiilor
Algoritmi i programare 4

Fiierul llin.cpp
#include llin.h int listaVida(LLin *l){ /* aloca memorie pentru tablou */ l->tab = new Elt[MAX_LLIN]; if (l->tab == NULL) return ERR_LLIN_MEM_INSUF; /* initializeaza numarul de elemente */ l->nrElt = 0;

/* operatie terminata cu succes */ return SUCCES;


}
Algoritmi i programare 5

Fiierul llin.cpp
int insereaza( LLin *l, Elt elt, int k ) { int j;

/* testeaza validitatea indicelui */ if ((k < 0) || (k > l->nrElt)) return ERR_LLIN_INDEX_GRESIT;


/* testeaza daca mai exista loc in tablou */ if (l->nrElt == MAX_LLIN-1) return ERR_LLIN_MEM_INSUF; /* deplaseaza elementele la dreapta */ for (j = l->nrElt-1; j >= k; j--) l->tab[j+1] = l->tab[j];
Algoritmi i programare 6

Fiierul llin.cpp
/* pune pe pozitia k noul element */ l->tab[k] = elt;

/* actualizeaza numarul de elemente */ l->nrElt++;


/* operatie terminata cu succes */ return SUCCES;

Algoritmi i programare

Fiierul llin.cpp
void parcurge(LLin *l, void viziteaza(Elt)) { int i; for (i = 0; i < l->nrElt; i++) viziteaza(l->tab[i]); }

Algoritmi i programare

Fiierul llin-demo.cpp
#include <iostream> #include "llin.h"

void afiseazaInt(int x) { std::cout << x << ' '; }

Algoritmi i programare

Fiierul llin-demo.cpp
void main(){ // declaratii... LLin lista; listaVida(&lista); for (i=1; i<8; i++){ e = i; if (coderr = insereaza(&lista, e, i-1)) cout << \nERR LLIN: << coderr << \n; parcurge(&lista, afiseazaInt);

}
Algoritmi i programare 10

LLin: implementarea cu liste inlnuite


L = (e0,, en-1)
L.prim e0

e1

en-1

Algoritmi i programare

11

LLin: implementarea cu liste inlnuite


struct NodLlin { Elt elt; struct NodLLin *succ; };
struct LLin { NodLlin *prim; int nrElt; };
Algoritmi i programare 12

LLin: implementarea cu liste inlnuite


int insereaza( LLin *l, Elt elt, int k ) { int j; NodLlin *p, *q;
/* testeaza exceptiile */ if ((k < 0) || (k > l->nrElt)) return ERR_LLIN_INDEX_GRESIT;

/* aloca spatiu pentru noul nod */ q = new NodLlin; if (q == NULL) return ERR_LLIN_MEM_INSUF; /* memoreaza noua informatie */ q->elt = elt;
Algoritmi i programare 13

LLin: implementarea cu liste inlnuite


/* stabileste noile legaturi */ if ((k == 0) || (l->prim == NULL)) { //primul sau lista vida q->succ = l->prim; l->prim = q; } else { // nu-i primul si lista nevida for (p = l->prim, j = 0; j < k-1; j++) p = p->succ; q->succ = p->succ; p->succ = q; } /* actualizeaza numarul de elemente */ l->nrElt++; /* operatie terminata cu succes */ return SUCCES; }
Algoritmi i programare 14

LLin: implementarea cu liste inlnuite


int i, e, coderr; LLin lista; listaVida(&lista); for (i=1; i<8; i++) { e = i; if (coderr = insereaza(&lista, e, i-1)) cout << \nERR LLIN: << coderr << \n; } parcurge(&lista, afiseazaInt);
Algoritmi i programare 15

Recursie. Funcii recursive


Funcia f() apeleaz direct funcia g() dac n definiia lui f() exist un apel la g() Funcia f() apeleaz indirect funcia g() dac f() apeleaz direct o funcie h(), iar h() apeleaz direct sau indirect funcia g()
Funcia f() este definit recursiv daca ea se auto-apeleaz direct sau indirect
Algoritmi i programare 16

Recursie. Funcii recursive


Definiia unei funcii recursive cuprinde: Testarea cazului de baz condiia de oprire a apelului recursiv Apelul recursiv (cazul general): o variabil (ntreag) este transmis ca parametru funciei nsi, n aa fel ca dup un numr de pai s se ating cazul de baz Exist i funcii recursive far parametri
Algoritmi i programare 17

Funcii recursive. Exemplu


Definiia funciei factorial:
Cazul de baz: 0! = 1 Cazul general: n! = n*((n-1)!), n>0

int factorial(int n){ if(n <= 1) return 1; else return (n*factorial(n-1)); }


Algoritmi i programare 18

Apelul recursiv:
fact(4)

4*6 = 24 3*2 = 6 2*1 = 2

fact(3)

fact(2)

fact(1)

1
19

Algoritmi i programare

Exemplu de apel fr sfrit


#include <iostream> int main(){ cout << Universul este infinit!; main(); return 0; }

Algoritmi i programare

20

factorial(n) - varianta iterativ


int factorial(int n){ int produs = 1; for(; n > 1; --n) produs *= n; return produs; }

Valoarea returnata de factorial(n) este corecta doar pentru valorile lui n pentru care n! <= INT_MAX
Algoritmi i programare 21

Funcie recursiv fr parametri


#include <iostream> void scrie(void); int main(){ cout << "Introdu un text pe o linie:\n"; scrie(); /* scrierea textului in ordine inversa */ getchar(); return 0; } void scrie(void){ /* functie recursiva */ int c; if((c = getchar()) != '\n') /* conditia de oprire */ scrie(); /* apel recursiv */ putchar(c); } /* Introdu un text pe o linie: Textul acesta este un test pentru recursie eisrucer urtnep tset nu etse atseca lutxeT Algoritmi i programare 22 */

Recursie vs. iteraie: Fibonacci recursiv


f(0) = 0, f(1) = 1, f(n) = f(n-1) + f(n-2), n > 1
long int fib(int n){ if(n <= 1) return (long)n; else return(fib(n-1) + fib(n-2)); }

Algoritmi i programare

23

Fibonacci recursiv: arbore apeluri


fib(5) fib(4) fib(3)

fib(3)

fib(2)

fib(2)

fib(1)

fib(2)

fib(1)

fib(1)

fib(0)

fib(1)

fib(0)

fib(1)

fib(0)

Algoritmi i programare

24

Numr de apeluri
n fib(n) apeluri

2 24 42 43

1 46368 267914296 433494437

3 150049 866988873 1402817465


25

Algoritmi i programare

Recursie vs. iteraie: Fibonacci iterativ


long int ifib(int n){ int k; long f0 = 0, f1 = 1, temp; if(n <= 1) return (long)n; else for (k = 2; k <= n; ++k) { temp = f1; f1 += f0; f0 = temp; } return f1; }
Algoritmi i programare 26

Turnurile din Hanoi


void muta(int n, char a, char b, char c){ if (n == 1) cout a << " -> " << b << \n; else { muta(n-1, a, c, b); cout a << " -> " << b << \n; muta(n-1, c, b, a); } }

Algoritmi i programare

27

Cel mai mare divizor comun


int cmmdc(int m, int n){ if(m == n) return m; else{ if(m > n)return cmmdc(m-n, n); else return cmmdc(m, n-m); } }

cat este de eficient?


Algoritmi i programare 28

S-ar putea să vă placă și