Você está na página 1de 29

Aula 6 - Recursividade

David Menotti Algoritmos e Estruturas de Dados I DECOM UFOP

Conceito de Recursividade

Fundamental em Matemtica e Cincia da Computao

Um programa recursivo um programa que chama a si mesmo Uma funo recursiva definida em termos dela mesma Nmeros naturais, Funo fatorial, rvore Define conjuntos infinitos com comandos finitos
Algoritmos e Estrutura de Dados I

Exemplos

Conceito poderoso

Renato Ferreira David Menotti

Recursividade

A recursividade uma estratgia que pode ser utilizada sempre que o clculo de uma funo para o valor n, pode ser descrita a partir do clculo desta mesma funo para o termo anterior (n-1).
Exemplo Funo fatorial: n! = n * (n-1) * (n-2) * (n-3) *....* 1 (n-1)! = (n-1) * (n-2) * (n-3) *....* 1 logo: n! = n * (n-1)!

David Menotti

Algoritmos e Estrutura de Dados I

Recursividade

Definio: dentro do corpo de uma funo, chamar novamente a prpria funo

recurso direta: a funo A chama a prpria funo A recurso indireta: a funo A chama uma funo B que, por sua vez, chama A

David Menotti

Algoritmos e Estrutura de Dados I

Condio de parada

Nenhum programa nem funo pode ser exclusivamente definido por si


Um programa seria um loop infinito Uma funo teria definio circular Permite que o procedimento pare de se executar F(x) > 0 onde x decrescente Estudar recursividade como ferramenta prtica!
Algoritmos e Estrutura de Dados I

Condio de parada

Objetivo

Renato Ferreira David Menotti

Recursividade

Para cada chamada de uma funo, recursiva ou no, os parmetros e as variveis locais so empilhados na pilha de execuo.

David Menotti

Algoritmos e Estrutura de Dados I

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 desempilhado e a execuo volta ao subprograma que chamou a funo
Algoritmos e Estrutura de Dados I

David Menotti

Exemplo
Fat (int n) { if (n<=0) return 1; else return n * Fat(n-1); } Main() { int f; f = fat(5); printf(%d,f); }
David Menotti
Algoritmos e Estrutura de Dados I

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 I

David Menotti

Recursividade

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

David Menotti

Algoritmos e Estrutura de Dados I

Fibonacci

Outro exemplo: Srie de Fibonacci:


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); }


David Menotti
Algoritmos e Estrutura de Dados I

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!!!

David Menotti

Algoritmos e Estrutura de Dados I

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;

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


Algoritmos e Estrutura de Dados I

David Menotti

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)

David Menotti

Algoritmos e Estrutura de Dados I

Dividir para Conquistar

Duas chamadas recursivas

Cada uma resolvendo a metade do problema Soluo eficiente de problemas Decomposio Duas chamadas recursivas

Muito usado na prtica


No se reduz trivialmente como fatorial

No produz recomputao excessiva como fibonacci

Pores diferentes do problema


Algoritmos e Estrutura de Dados I

David Menotti

Outros exemplos de recursividade


void estrela(int x,int y, int r) { if ( r > 0 ) { estrela(x-r, y+r, r div 2); estrela(x+r, y+r, r div 2); estrela(x-r, y-r, r div 2); estrela(x+r, y-r, r div 2); box(x, y, r); } }

David Menotti

Algoritmos e Estrutura de Dados I

Exemplo simples: rgua


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

David Menotti

Algoritmos e Estrutura de Dados I

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)
David Menotti
Algoritmos e Estrutura de Dados I

Anlise de Complexidade O

Define-se uma funo de complexidade f(n) desconhecida

n mede o tamanho dos argumentos para o procedimento em questo Especifica-se T(n) como uma funo dos termos anteriores Especifica-se a condio de parada (e.g. T(1))

Identifica-se a equao de recorrncia T(n):

David Menotti

Algoritmos e Estrutura de Dados I

Anlise da Funo Fatorial

Qual a equao de recorrncia que descreve a complexidade da funo fatorial?


T(n) = 1 + T(n-1) T(1) = 1

T(n) = 1 + T(n-1) T(n-1) = 1 + T(n-2) T(n-2) = 1 + T(n-3) ... T(2) = 1 + T(1)

David Menotti

Algoritmos e Estrutura de Dados I

Anlise de Funes Recursivas

Alm da anlise de custo do tempo, deve-se analisar tambm o custo de espao Qual a complexidade de espao da funo fatorial (qual o tamanho da pilha de execuo)?

David Menotti

Algoritmos e Estrutura de Dados I

Anlise da Funo Recursiva

Considere a seguinte funo:

Pesquisa(n) { (1) if (n <= 1) (2) inspecione elemento e termine; else { (3) para cada um dos n elementos inspecione elemento; (4) Pesquisa(n/3) ; }

}
David Menotti
Algoritmos e Estrutura de Dados I

Anlise da Funo Recursiva

Qual a equao de recorrncia?


T(n) = n + T(n/3) T(1) = 1

Resolva a equao de recorrncia

Dicas:

Pode fazer a simplificao de n ser sempre divisvel por 3 Somatrio de uma PG finita: (a0 rn)/(1-r)
Algoritmos e Estrutura de Dados I

David Menotti

Resolvendo a equao

Substitui-se os termos T(k), k < n, at que todos os termos T(k), k > 1, tenham sido substitudos por frmulas contendo apenas T(1).

1 n/3K = 1 n = 3K

David Menotti

Algoritmos e Estrutura de Dados I

Resolvendo a Equao
Considerando que T(n/3K) = T(1) temos:
K-1 K-1

T(n) = (n/3i) + T(1) = n (1/3i) + 1


i=0 i=0

Aplicando a frmula do somatrio de uma PG finita (a0 rn)/(1-r), temos: n (1 (1/3)K)/(1 -1/3) + 1 n (1 (1/3K))/(1 -1/3) + 1 n (1 (1/n))/(1 -1/3) + 1 (n 1)/(2/3) + 1 3n/2
David Menotti

O(n)
Algoritmos e Estrutura de Dados I

Exerccio

Crie uma funo recursiva que calcula a potncia de um nmero:

Como escrever a funo para o termo n em funo do termo anterior?

Qual a condio de parada?

Qual a complexidade desta funo?

David Menotti

Algoritmos e Estrutura de Dados I

Funo de Potncia Recursiva


int pot(int base, int exp) { if (!exp) return 1; /* else */ return (base*pot(base, exp-1)); } Anlise de complexidade: T(0) = 1; T(b,n) = 1 + T(b,n-1);

O(n)

David Menotti

Algoritmos e Estrutura de Dados I

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); }

David Menotti

Algoritmos e Estrutura de Dados I

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

David Menotti

Algoritmos e Estrutura de Dados I

Você também pode gostar