O documento discute recursividade e como resolver problemas de forma recursiva. Explica que uma função recursiva é aquela que se chama a si mesma e que a recursividade envolve dividir um problema em subproblemas menores do mesmo tipo até chegar a um caso trivial. Fornece como exemplo a função fatorial definida recursivamente.
2. Uma função ou método é chamado recursivo
quando dentro dele existe uma chamada para
ele próprio.
Exemplo:
Chamada Recursiva
3. Se a natureza dos subproblemas é a mesma do
problema, o mesmo método usado para reduzir
o problema pode ser usado para reduzir os
subproblemas e assim por diante.
A recursividade é uma forma interessante de
resolver problemas por meio da divisão dos
problemas em problemas menores de mesma
natureza.
Quando devemos parar?
Quando alcançarmos um caso trivial que
conhecemos a solução.
Caso fácil de resolver,
onde a solução é
simples
4. Qual o fatorial de zero?
Quanto é um dado x multiplicado por 1?
Quanto é um dado x multiplicado por 0?
Quanto é x elevado a 1?
Quantos elementos possui um vetor vazio?
Exemplos de casos triviais:
5. Muitas funções podem ser definidas
recursivamente, para isso é necessário
identificar as duas partes acima.
Qualquer problema resolvido de forma
iterativa também pode ser resolvido de forma
recursiva.
Assim um processo recursivo para resolução
de um problema consiste em duas partes:
1. O caso trivial, cuja solução é conhecida;
2. Um método geral que reduz o problema a um ou
mais problemas menores (subproblemas) de
mesma natureza.
6. Exemplo função fatorial:
A função fatorial de um inteiro não negativo
pode ser definida como:
𝑛! =
1 𝑛 = 0
𝑛 ∗ 𝑛 − 1 ! 𝑛 > 0
Essa definição estabelece um processo recursivo
para calcular o fatorial de um inteiro n.
Caso trivial: n=0. Neste caso n! = 1.
Método geral: 𝑛 ∗ 𝑛 − 1 !.
7. Assim, usando-se este processo recursivo, o
calculo de 4!, por exemplo, é feito como a
seguir:
4! =
8. Assim, usando-se este processo recursivo, o
calculo de 4!, por exemplo, é feito como a
seguir:
4! = 4 * 3!
9. Assim, usando-se este processo recursivo, o
calculo de 4!, por exemplo, é feito como a
seguir:
4! = 4 * 3!
= 4 * (3 * 2!)
10. Assim, usando-se este processo recursivo, o
calculo de 4!, por exemplo, é feito como a
seguir:
4! = 4 * 3!
= 4 * (3 * 2!)
= 4 * (3 * (2 * 1!))
11. Assim, usando-se este processo recursivo, o
calculo de 4!, por exemplo, é feito como a
seguir:
4! = 4 * 3!
= 4 * (3 * 2!)
= 4 * (3 * (2 * 1!))
= 4 * (3 * (2 * (1 * 0!)))
Caso Trivial, fácil de
resolver, onde a
solução é simples
0! = 1
12. Assim, usando-se este processo recursivo, o
calculo de 4!, por exemplo, é feito como a
seguir:
4! = 4 * 3!
= 4 * (3 * 2!)
= 4 * (3 * (2 * 1!))
= 4 * (3 * (2 * (1 * 0!)))
= 4 * (3 * (2 * (1 * 1)))
13. Assim, usando-se este processo recursivo, o
calculo de 4!, por exemplo, é feito como a
seguir:
4! = 4 * 3!
= 4 * (3 * 2!)
= 4 * (3 * (2 * 1!))
= 4 * (3 * (2 * (1 * 0!)))
= 4 * (3 * (2 * (1 * 1)))
= 4 * (3 * (2 * 1))
14. Assim, usando-se este processo recursivo, o
calculo de 4!, por exemplo, é feito como a
seguir:
4! = 4 * 3!
= 4 * (3 * 2!)
= 4 * (3 * (2 * 1!))
= 4 * (3 * (2 * (1 * 0!)))
= 4 * (3 * (2 * (1 * 1)))
= 4 * (3 * (2 * 1))
= 4 * (3 * 2)
15. Assim, usando-se este processo recursivo, o
calculo de 4!, por exemplo, é feito como a
seguir:
4! = 4 * 3!
= 4 * (3 * 2!)
= 4 * (3 * (2 * 1!))
= 4 * (3 * (2 * (1 * 0!)))
= 4 * (3 * (2 * (1 * 1)))
= 4 * (3 * (2 * 1))
= 4 * (3 * 2)
= 4 * 6
16. Assim, usando-se este processo recursivo, o
calculo de 4!, por exemplo, é feito como a
seguir:
4! = 4 * 3!
= 4 * (3 * 2!)
= 4 * (3 * (2 * 1!))
= 4 * (3 * (2 * (1 * 0!)))
= 4 * (3 * (2 * (1 * 1)))
= 4 * (3 * (2 * 1))
= 4 * (3 * 2)
= 4 * 6
= 24
int fat(int n)
{
if (n == 0)
return 1;
else
return n*fat(n-1);
}
Mas como uma função
recursiva é de fato
implementada no computador?
Usando-se um mecanismo
chamado de PILHA DE EXECUÇÃO!
17. Considere, novamente, o exemplo para 4! :
int fatorial(int n)
{
if (n == 0)
return 1;
else
return n * fatorial(n - 1);
}
Pilha de execução:
fatorial(4)
fatorial(3)
fatorial(2)
fatorial(1)
fatorial(0)
→ return 4 * fatorial(3)
→ return 3 * fatorial(2)
→ return 2 * fatorial(1)
→ return 1 * fatorial(0)
→ return 1 (caso trivial)
25. “Para fazer um processo recursivo é preciso ter
fé”. prof. Siang Wun Song
“Ao tentar resolver o problema, encontrei
obstáculos dentro de obstáculos. Por isso adotei
uma solução recursiva!”.
“To undestand recursion, we must first
understand recursion.”
26.
27.
28.
29.
30. Presente em praticamente todas as linguagens,
como: C, C++, Java, Pascal, JavaScript, Python...
Muitos algoritmos complexos são resolvidos
através de soluções recursivas
QuickSort
MergeSort
Busca Binária
Muitas estruturas de dados são recursivas:
Arvores Binárias
Listas encadeadas
Tendem a gerar códigos menores que as iterativas
31. Codifique uma função que multiplica um dado
inteiro “a” por um inteiro “b”, usando somas
sucessivas.
Exemplo: 4 * 3 = 3 + 3 + 3 + 3 = 12
int mult(int a, int b) {
}
32. Codifique uma função que multiplica um dado
inteiro “a” por um inteiro “b”, usando somas
sucessivas.
Exemplo: 4 * 3 = 3 + 3 + 3 + 3 = 12
int mult(int a, int b) {
if (a == 0)
return
}
33. Codifique uma função que multiplica um dado
inteiro “a” por um inteiro “b”, usando somas
sucessivas.
Exemplo: 4 * 3 = 3 + 3 + 3 + 3 = 12
int mult(int a, int b) {
if (a == 0)
return 0;
}
34. Codifique uma função que multiplica um dado
inteiro “a” por um inteiro “b”, usando somas
sucessivas.
Exemplo: 4 * 3 = 3 + 3 + 3 + 3 = 12
int mult(int a, int b) {
if (a == 0)
return 0;
if (a == 1)
return
}
35. Codifique uma função que multiplica um dado
inteiro “a” por um inteiro “b”, usando somas
sucessivas.
Exemplo: 4 * 3 = 3 + 3 + 3 + 3 = 12
int mult(int a, int b) {
if (a == 0)
return 0;
if (a == 1)
return b;
}
36. Codifique uma função que multiplica um dado
inteiro “a” por um inteiro “b”, usando somas
sucessivas.
Exemplo: 4 * 3 = 3 + 3 + 3 + 3 = 12
int mult(int a, int b) {
if (a == 0)
return 0;
if (a == 1)
return b;
return b + mult(a-1,b);
}
Método geral:
Como a soma
sucessiva será
aplicada a b então
teremos
b+mult(a-1,b).
O a-1 é porque
uma soma já foi
realizada.
37. mult(3,5) = if (a == 0)
return 0;
if (a == 1)
return b;
return b+mult(a-1,b);
Trecho código
38. mult(3,5) = 5 + mult(3-1,5) if (a == 0)
return 0;
if (a == 1)
return b;
return b+mult(a-1,b);
Trecho código
39. mult(3,5) = 5 + mult(3-1,5)
= 5 + mult(2,5)
if (a == 0)
return 0;
if (a == 1)
return b;
return b+mult(a-1,b);
Trecho código
40. mult(3,5) = 5 + mult(3-1,5)
= 5 + mult(2,5)
= 5 + 5 + mult(2-1,5)
if (a == 0)
return 0;
if (a == 1)
return b;
return b+mult(a-1,b);
Trecho código
41. mult(3,5) = 5 + mult(3-1,5)
= 5 + mult(2,5)
= 5 + 5 + mult(2-1,5)
= 5 + 5 + mult(1,5)
if (a == 0)
return 0;
if (a == 1)
return b;
return b+mult(a-1,b);
Trecho código
53. 1. Implemente o código em Java da função que
multiplica um dado inteiro “a” por um inteiro “b”,
usando somas sucessivas.
2. Sequencia de Fibonacci
É uma sequência de números inteiros, começando
normalmente por 0 e 1, na qual, cada termo
subsequente corresponde a soma dos dois anteriores.
Exemplo: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
Caso trivial: n=0 ou n=1. Neste caso retorne n.
Método geral: retorne fib(n-2)+fib(n-1)
3. Responda o que é uma função recursiva?
54. 4. Escreva um programa em Java que atribua valores
aleatórios a um vetor de 20 elementos inteiros.
Ordene o vetor e imprima seu conteúdo na tela.
Leia do usuário um valor e realize a busca recursiva do
mesmo dentro do vetor de acordo com o algoritmo
abaixo.
55. import java.util.*;
public class NumAleat {
public static void main(String[] args) {
Random gerador = new Random();
// imprime sequência de 10 números inteiros aleatórios
// entre 0 e 20
for (int i = 0; i < 10; i++)
System.out.println(gerador.nextInt(21));
}
}
Números aleatórios em Java