Sei sulla pagina 1di 4

Recursividade

Recursividade

Sees 2.2 e 1.4 do livro Projeto e Anlise de Algoritmos

Um procedimento que chama a si mesmo, direta ou indiretamente, dito ser recursivo. Recursividade permite descrever algoritmos de forma mais clara e concisa, especialmente problemas recursivos por natureza ou que utilizam estruturas recursivas. Exemplos
Algoritmos de Dividir para Conquistar rvores
Algoritmos e Estrutura de Dados II

Exemplo
Fatorial: n! = n*(n-1)! p/ n>0 0! = 1 Em C
Fat (int n) { if (n<=0) return 1; else return n * Fat(n-1); }
Algoritmos e Estrutura de Dados II

Estrutura
Normalmente, as funes recursivas so divididas em duas partes
Chamada Recursiva Condio de Parada

A chamada recursiva pode ser direta (mais comum) ou indireta (A chama B que chama A novamente) A condio de parada fundamental para evitar a execuo de loops infinitos
Algoritmos e Estrutura de Dados II

Execuo
Internamente, quando qualquer chamada de funo feita dentro de um programa, criado um Registro de Ativao na Pilha de Execuo do programa O registro de ativao armazena os parmetros e variveis locais da funo bem como o ponto de retorno no programa ou subprograma que chamou essa funo. Ao final da execuo dessa funo, o registro desemplihado e a execuo volta ao subprograma que chamou a funo
Algoritmos e Estrutura de Dados II

Exemplo
Fat (int n) { if (n<=0) return 1; else return n * Fat(n-1); }

Main() { int f; f = fat(5); printf(%d,f); }


Algoritmos e Estrutura de Dados II

Complexidade
A complexidade de tempo do fatorial recursivo O(n). (Em breve iremos ver a maneira de calcular isso usando equaes de recorrncia) Mas a complexidade de espao tambm O(n)!, devido a pilha de execuo Ja no fatorial no recursivo a complexidade de espao O(1)
Fat (int n) { int f; f = 1; while(n > 0){ f = f * n; n = n 1; } return f; }
Algoritmos e Estrutura de Dados II

Recursividade
Portanto, a recursividade nem sempre a melhor soluo, mesmo quando a definio matemtica do problema feita em termos recursivos

Algoritmos e Estrutura de Dados II

Fibonnaci
Outro exemplo: Srie de Fibonnaci:
Fn = Fn-1 + Fn-2 n > 2, F0 = F1 = 1 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89...
Fib(int n) { if (n<2) return 1; else return Fib(n-1) + Fib(n-2); }
Algoritmos e Estrutura de Dados II

Anlise da funo Fibonacci


Ineficincia em Fibonacci
Termos Fn-1 e Fn-2 so computados independentemente Nmero de chamadas recursivas = nmero de Fibonacci! Custo para clculo de Fn
O(n) onde = (1 + 5)/2 = 1,61803... Golden ratio Exponencial!!!

Algoritmos e Estrutura de Dados II

Fibonacci no recursivo
int FibIter(int n) { int i, k, F; i = 1; F = 0; for (k = 1; k <= n; k++) { F += i; i = F - i; } return F; }

Quando vale a pena usar recursividade


Recursividade vale a pena para Algoritmos complexos, cuja a implementao iterativa complexa e normalmente requer o uso explcito de uma pilha
Dividir para Conquistar (Ex. Quicksort) Caminhamento em rvores (pesquisa, backtracking)

Complexidade: O(n) Concluso: no usar recursividade cegamente!


Algoritmos e Estrutura de Dados II Algoritmos e Estrutura de Dados II

Dividir para Conquistar


Duas chamadas recursivas
Cada uma resolvendo a metade do problema

Exemplo simples: rgua


void regua(int l, r, h){ int m; if (h > 0) { m = (l + marca(m, regua(l, regua(m, } }

Muito usado na prtica


Soluo eficiente de problemas Decomposio

No se reduz trivialmente como fatorial


Duas chamadas recursivas

r) / 2; h); m, h 1); r, h 1);

No produz recomputao excessiva como fibonacci


Pores diferentes do problema
Algoritmos e Estrutura de Dados II Algoritmos e Estrutura de Dados II

Execuo: rgua
regua(0, 8, 3) marca(4, 3) regua(0, 4, 2) marca(2, 2) regua(0, 2, 1) marca(1, 1) regua(0, 1, 0) regua(1, 2, 0) regua(2, 4, 1) marca(3, 1) regua(2, 3, 0) regua(3, 4, 0) regua(4, 8, 2) marca(6, 2) regua(4, 6, 1) marca(5, 1) regua(4, 5, 0) regua(5, 6, 0) regua(6, 8, 1) marca(7, 1) regua(6, 7, 0) regua(7, 8, 0) de Dados II Algoritmos e Estrutura

Representao por rvore


0, 8, 3

0, 4, 2

4, 8, 2

0, 2, 1

2, 4, 1

4, 6, 1

6, 8, 1

0, 1, 0

1, 2, 0

2, 3, 0

3, 4, 0

4, 5, 0

5, 6, 0

6, 7, 0

7, 8, 0

Algoritmos e Estrutura de Dados II

Outros exemplos de recursividade


void estrela(int x, y, r) { if (r > 0) { estrela(x-r, y+r, r / 2); estrela(x+r, y+r, r / 2); estrela(x-r, y-r, r / 2); estrela(x+r, y-r, r / 2); box(x, y, r); } } x e y so as coordenadas do centro. r o valor da metade do lado

Exerccios
Implemente uma funo recursiva para computar o valor de 2n O que faz a funo abaixo?
void f(int a, int b) { // considere a > b if (b = 0) return a; else return f(b, a % b); }
Algoritmos e Estrutura de Dados II

Algoritmos e Estrutura de Dados II

Respostas
Pot(int n) { if (n==0) return 1; else return 2 * Pot(n-1); }

Algoritmo de Euclides. Calcula o MDC (mximo divisor comum) de dois nmeros aeb

Algoritmos e Estrutura de Dados II

Potrebbero piacerti anche