Estrutura de Dados
Tema 2: Recursividade.
Objetivos desse encontro
• Entender o conceito de recursividade; • Criar funções recursivas;
• Comparar soluções recursivas e iterativas.
Relembrando ... Função
• Solução adotada para dividir um programa em módulos, que executa, ações bem específicas;
• Os módulos podem ser reutilizados quantas vezes forem necessários.
• Todo programa escrito em C possui,
Função escrita antes da
main
# include < stdio.h>
int dobro( int n) { n = n * 2; return n; }
int main() { int a; res;
printf(“Digite um valor: “); scanf(“% d”, &a); res = dobro(a);
printf(“Dobro = % d”, res); getchar(); }
Função escrita depois da
main
# include < stdio.h>
int dobro( int n) ;
int main() { int a; res;
printf(“Digite um valor: “); scanf(“% d”, &a); res = dobro(a);
printf(“Dobro = % d”, res); getchar(); }
int dobro( int n) { n = n * 2; return n; }
Tipos de funções
• Não recebem parâmetros e não retornam valor
void funcao( ) { ...
}
• Recebem parâmetros e não retornam valor
void funcao( par1, ...) { ...
Tipos de funções
• Não recebem parâmetros e retornam valor
tipo funcao( ) { ...
return x; }
• Recebem parâmetros e retornam valor
tipo funcao( par1, ...) { ...
return x; }
Funções iterativas
• I teração significa repetição.
• Funções iterativas realizam um
procedimento repetitivo para gerar um resultado.
• Cada iteração (ou cada repetição) resolve um pedaço do problema. Quando a repetição termina, o problema está resolvido
Exemplo de funções iterativas
# include < stdio.h>
int potencia( int b, int e) ;
int main(void) { int base, exp, result; base = 2;
exp = 3;
int potencia( int b, int e) { int i, r = 1;
for (i = 1; i < = e; i+ + ) { r = r * b;
} return r; }
Continuando
Tema 2: Recursividade.
O que é Recursividade?
• Alguma coisa que é definida em termos dela própria.
• É a possibilidade de representar um
problema em função
dele próprio, contudo, numa instância menor. • Diminuir o problema até
Exemplo de Recursividade
1) Cálculo da potência de um número: 24é bem mais fácil de calcular que 2876.
Entretanto, o problema é o mesmo, o que muda é a instância do problema (ou o tamanho do problema).
Exemplo de Recursividade
24=
2 * 23
23= 2 * 22
22= 2 * 21
21= 2
Exemplo de Recursividade
2) Cálculo do fatorial de um número: 4! é bem mais fácil de calcular que 345! Entretanto, o problema é
Exemplo de Recursividade
4! = 4 * 3!
3! = 3 * 2! 2! = 2 * 1!
1! = 1
Características importantes para
funções recursivas
• Possuem uma função de recorrência; • Possuem uma condição que identifica o
momento de interromper a recorrência; • Possuem sempre ao
menos uma instância do problema para a qual a solução é facilmente obtida.
Função recursiva para calcular uma
potência
24=
2 * 23
23= 2 * 22
22= 2 * 21
21= 2
Supondo uma potência genérica be: • Função de recorrência: be= b * be-1
• I nstância com solução conhecida: b1= b
Função recursiva da potência em C
# include< stdio.h>
int potencia( int b, int e) ;
int main() { int b, e, r;
printf(“Valor base? “); scanf(“% d”, &b); printf(“Valor expoente? “); scanf(“% d”, &e); r = potencia(b, e);
printf(“\ nPotencia = % d“, r); getchar(); }
int potencia( int b, int e) {
int pot = 0; if (e = = 1) pot = b; else
pot = b * potencia(b, -1); return pot;
}
23
2 * 22
2 * 21
2 E 1
E 2
E 3
2 4 8
Função recursiva do fatorial em C
# include< stdio.h>
int fatorial( int n) ;
int main() { int num, fat; printf(“Número? “); scanf(“% d”, &num); fat = fatorial(num); printf(“Fatorial= % d“,fat); getchar();
}
int fatorial( int n) {
int f = 1, i; if (n = = 0 | | n = = 1)
f = 1;
else f = n * fatorial (n-1); return f;
}
3!
3 * 2!
2 * 1!
1 E 1
E 2
E 3
1 2 6 fatorial ( n= 3) = 6
Agora é sua Vez
Tema 2: Recursividade.
Aplicação de Recursividade
Problema 1: Determinar o n-ésimo
elemento da sequência de Fibonacci. 0 – 1 – 1 – 2 – 3 – 5 – 8 – 13 – 21 - ...
Resolvendo o problema …
• Função de recorrência:
fib(pos) = fib(pos-1) + fib(pos-2)
• I nstância com solução conhecida: fib(1) = 0
fib(2) = 1
# include < stdio.h>
int fibonacci( int pos) ;
int main(void) { int pos, n;
printf(“Posicao do nº desejado?”); scanf(“% d”, &pos);
n= fibonacci(pos); println(“Numero= % d”, n); getchar();
}
int fibonacci( int p) {
int n= -1; if (p = = 1)
n = 0; else if (p = = 2)
n = 1;
else n= fibonacci(p-1)+ fibonacci(p-2);
return n; }
Analisando a execução ...
fib(4)
fib(3)
1
fib(2)
fib(2) fib(1) fib(0)
+
+ fib(1) +
0 1
0 1
Aplicação de Recursividade
Problema 2: Descobrir se um número está cadastrado em um vetor ordenado. Se o número for encont rado, most rar sua posição dentro do vetor.
2 5 8 10 28 35
0 1 2 3 4 5
2 5 8 10 28 35
0 1 2 3 4 5 i = 0
f = 5 meio = 2
meio
2 5
0 1
10 28 35
3 4 5
Resolvendo o problema ...
• Função de recorrência:
busca(el, i, f)= busca(vetor, el, i, meio-1) OU busca(vetor, el, meio+ 1, f)
• I nstância com solução conhecida: vetor(meio) = = el
número encontrado na posição pos.
# include < stdio.h>
int busca( int vet[ ] , int el, int i, int f) ; int main() {
int n, p, vet[ ] = { 2, 5, 8, 10, 28, 35} ; printf(“Numero a ser pesquisado? "); scanf(“% d”, &n);
p = busca (vet, n, 0, 5);
if (p = = -1)
printf(“Numero não está no vetor.”); else printf("Numero está na posicao % d”, p); getch();
}
int busca( int vet[ ] , int el, int i, int f) { int meio, pos;
if (i > f ) pos = -1; else { meio = (i + f ) / 2;
if (el = = vet[ meio] ) pos = meio; else if (el < vet[ meio] )
pos= busca(vet, el, i, meio-1); else pos= busca(vet, el, meio+ 1, f ); }
Finalizando
Tema 2: Recursividade.
Função Recursiva X I terativa
• Praticamente todas as funções recursivas
podem ser convertidas para funções
iterativas.
• A condição de parada utilizada na versão recursiva pode ser aproveitada em uma estrutura de repetição, na versão iterativa.
Função iterativa da potência em C
int potencia( int b, int e) {
int pot = 1, i; for (i= 1; i< = e; i+ + ) {
pot = pot * b; }
Função iterativa do fatorial em C
int fatorial( int n) {
int f = 1, i; if (n = = 0 | | n = = 1)
f = 1;
else { for (i= n; i> = 1; i--) f = f * i; }
return f; }
int busca( int vet[ ] , int el, int i, int f) {
int meio, pos= -1; while (i < = f) {
meio = (i + f) / 2; if (el = = vet[ meio] )
f = i -1;
else if (el < vet[ meio] ) f = meio – 1; else i = meio + 1; }
return pos;}
Função iterativa do fatorial em C
Conclusões
• Recursividade pode ser usada em situações específicas;
• Funções recursivas consomem mais memória; • Funções recursivas