Recursividade PDF
Recursividade PDF
Recursividade PDF
Assunto: Recursividade
1. Introduo: recursividade
1
Pela equao anterior, podemos deduzir que qualquer fatorial pode ser calculado
como o seu valor multiplicado pelo fatorial do seu valor subtrado por um. E quanto vale
o fatorial de n1? R: (n1)!=(n1)(n2)!
Podemos propor uma funo que tenta calcular a equao acima:
static long fatorial(long n) {
return n * (n-1)!
}
Entretanto, existe um erro grave nesta funo: se a funo chama ela mesma, quando esta
funo termina e retorna? R.: Da forma que est, no termina... :'(
O principal problema do exemplo anterior que a funo no sabe quando terminar! Deste
modo, toda funo recursiva precisa ter uma condio de trmino. Toda funo recursiva deve ter
uma lgica similar ao demonstrado a seguir:
static void funcRecursiva() {
// Parte Trivial
if (<conhecemos_a_resposta>)
return <resposta>;
// Parte Geral
else
return funcRecursiva();
}
No caso do fatorial, sabemos que o fatorial de 0 1. Esta a nossa parte TRIVIAL. Ento,
podemos alterar o cdigo fatorial recursivo proposto da seguinte forma:
static long fatorial(long n) {
// Parte Trivial
if (n <= 1)
return 1;
// Parte Geral
else
return n * fatorial(n-1);
}
Um algoritmo para solucionar a torre de Hani no trivial, mas podemos utilizar a recurso
com o objetivo de dividir para conquistar. A chave para resolver este problema quebrar o
desafio em desafios menores at que o desafio seja trivial. Neste caso, o trivial quando temos
apenas um nico disco para mover (neste caso, basta mover o disco direto).
Exemplificando, se queremos mover os discos da haste 1 para a haste 3, e existem n discos na
haste 1, podemos mover os n1 discos para a haste auxiliar 2, mover o ltimo disco da haste 1 para
a haste 3 e, ento, levar os n1 discos da haste auxiliar 2 para a haste 3. Veja a figura a seguir:
3
Ou seja, a parte TRIVIAL da nossa recurso mover um disco da haste 1 para a haste C. A
parte GERAL (recursiva) vai ser mover os n1 discos da haste 1 para a haste 2 e depois mover da
haste 2 para a haste 3. Um possvel algoritmo seria:
void hanoi(){
// Parte TRIVIAL
if (numero_de_discos == 1)
<mover_o_disco_da_origem_para_o_destino>
// Parte GERAL
else
hanoi(<mover_n-1_discos_da_origem_para_o_auxiliar)
<mover_o_disco_da_origem_para_o_destino>
hanoi(<mover_n-1_discos_do_auxiliar_para_o_destino)
}
class app {
static void Hanoi(int num_discos, String hasteOrigem,
String hasteDestino, String hasteAuxiliar) {
// Parte TRIVIAL
if (num_discos == 1) {
System.out.println("Mover o disco da haste " + hasteOrigem +
" para a haste " + hasteDestino + ".");
// Parte GERAL
} else {
Hanoi(num_discos-1, hasteOrigem, hasteAuxiliar, hasteDestino);
System.out.println("Mover o disco da haste " + hasteOrigem +
" para a haste " + hasteDestino + ".");
Hanoi(num_discos-1, hasteAuxiliar, hasteDestino, hasteOrigem);
}
}
Agora tente desenvolver uma outra soluo para o problema da torre de Hani sem utilizar a
recurso. Pense um pouco e voc perceber que muito difcil (porm no impossvel).
2. Atividades em sala
Exerccio 1. A sequncia de Fibonacci uma srie que segue a seguinte regra: xn=xn1+xn2,
sendo que x1=1 e x2=1. Os primeiros elementos da sequncia de Fibonacci so: {1, 1, 2, 3, 5, 8, 13,
21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, ... }. Um possvel cdigo
para imprimir a sequencia de Fibonacci apresentado abaixo:
4
class app {
static int Fibonacci(int n) {
int n1 = 1, n2 = 1;
for (int i = 3; i <= n; i++) {
int t = n1;
n1 = n2;
n2 = n1 + t;
}
return n2;
}
static public void main(String s[]) {
System.out.println(Fibonacci(3));
System.out.println(Fibonacci(6));
System.out.println(Fibonacci(9));
System.out.println(Fibonacci(12));
}
}
Faa um cdigo que calcule a sequncia de Fibonacci utilizando recurso.
Exerccio 2. Pode-se calcular o mximo divisor comum (MDC) entre dois nmeros inteiros
positivos utilizando o algoritmo de Euclides. Veja a implementao do algoritmo de Euclides
abaixo:
class app {
static int Euclides(int a, int b) {
while (b != 0) {
int t = a;
a = b;
b = t % b;
}
return a;
}
static public void main(String s[]) {
System.out.println(Euclides(10,8));
System.out.println(Euclides(21,13));
System.out.println(Euclides(63,108));
}
}
Modifique o algoritmo acima de modo a utilizar recurso.