Recursividade Prof. Cesar Augusto Tacla Métodos iterativos Métodos iterativos utilizam estruturas de repetição For While Do while Normalmente, um método invoca outros métodos, não a si mesmo. 2 1
Recursividade Em programação, é o fato de um método invocar ele mesmo. Exemplos clássicos Fractais Torre de Hanoi Fatorial Fibonnaci Exemplos em http://www.krazydad.com/bestiary/bestiary_fern.html 3 Recursividade: aplicações Algoritmos de ordenação (sort) Busca em árvores Transformada rápida de Fourier utilizada em processamento de sinais Imagens de síntese Fonte http://www.cs.princeton.edu/introcs/23recursion 4 2
Exemplo de recursividade: fatorial É um função matemática recursiva, pois é definida em função dela mesmo Se n > 1 então n! = n * (n-1)! Se (n 0 or 1) então n! = 1 De outra forma se (n==0 or n==1) fatorial(n) = 1 se (n > 1) fatorial(n) = n * fatorial(n-1) 5 Exemplo: fatorial public class JFatorial { public static int fatorial(int n) { if (n == 1 n == 0) return 1; return n * fatorial(n-1); public static void main(string args[]) { int n=1; if (args.length > 0) { n = Integer.parseInt(args[0]); if (n > 0) System.out.println("Fatorial de " + n + " = " + fatorial(n)); 6 3
Exemplo: fatorial ao executar: java JFatorial 5 fatorial(5) fatorial(4) fatorial(3) fatorial(2) fatorial(1) return 1 return 2*1 return 3*2 return 4*6 return 5*24 PILHA (STACK) DE CHAMADA Fatorial(5) Fatorial(4) Fatorial(3) Fatorial(2) Fatorial(1) topo base 7 Exemplo fatorial: pontos importantes Caso base: retorna um valor calculado sem recursão public static int fatorial(int n) { if (n == 1 n == 0) return 1; return n * fatorial(n-1); Passo de redução: os valores dos argumentos da invocação recursiva devem convergir para o caso base stack overflow 8 4
Exercícios Até qual número é possível calcular antes de estourar a capacidade de armazenamento de um tipo de dado inteiro? Modifique o programa fatorial para que ele imprima a cada execução do método fatorial(int n) o valor de n no início do método e o valor retornado ao final. A cada chamada, os valores impressos devem ser identados em uma posição: *N = 3 **N = 2 ***N = 1 ***return 1 **return 2 *return 6 9 Exercícios Implemente a série de Fibonacci de maneira recursiva e não recursiva. Compare os tempos de execução para séries grandes Exemplo para N = 7 1: 1 = 1 2: 1 = 1 3: 2 = fib(2) + fib(1) 4: 3 = fib(3) + fib(2) 5: 5 = fib(4) + fib(3) 6: 8 = fib(5) + fib(4) 7: 13 = fib(6) + fib(5) Tecno-OO\RepositorioJAVA\JRecursividade\JFibonacci 10 5
Exercício Fibonacci: solução public class Fibonacci { public static long fib(int n) { if (n <= 1) return n; else return fib(n-1) + fib(n-2); public static void main(string[] args) { int N = Integer.parseInt(args[0]); System.out.println("*** recursivo ***"); for (int i = 1; i <= N; i++) System.out.println(i + ": " + fib(i)); Problema: tempo é exponencial Sol. http://www.dainf.ct.utfpr.edu.br/~tacla/javarepositorio/jrecursividade/jfibonacci 11 Fibonacci tempo exponencial Para calcular f(1) => 1 iteração F(2) = 1 F(3) = f(2) + f(1) = 2 F(4) = f(3) + f(2) = 2 + 1 = 3 F(5) = f(4) + f(3) = 3 + 2 = 5 F(6) = f(5) + f(4) = 5 + 3 = 8 F(7) = f(6) + f(5) = 8 + 5 = 13 F(8) = f(7) + f(6) = 13 + 8 = 21 F(9) = f(8) + f(7) = 21 + 13 = 34 F(10) = f(9) + f(8) = 34 + 21 = 55 12 6
Fibonacci tempo exponencial 60 50 40 Iterações 30 20 10 0 1 2 3 4 5 6 7 8 9 10 ordem 13 Fibonacci: solução iterativa public class FibonacciIterativo { public static void main(string[] args) { int N = Integer.parseInt(args[0]); long ultimo = 0; long penultimo = 1; long atual = 1; for (int i = 1; i <= N; i++) { atual = ultimo + penultimo; penultimo = ultimo; ultimo = atual; System.out.println(i + ": " + atual); Sol. http://www.dainf.ct.utfpr.edu.br/~tacla/javarepositorio/jrecursividade/jfibonacci 14 7
Exercício quadrados recursivos Faça um algoritmo recursivo que reproduza o padrão: 15 Árvore Árvore: é uma estrutura de dados onde os dados estão organizados de forma hierárquica. filho raiz filho É composto por um nó raiz e, normalmente, por vários nós filhos. folha folha folha Um nó que não possui filhos é dito folha. 16 8
Árvore binária Árvores binárias satisfazem aos critérios: Não possuem nós (árvores vazias) ou Apresentam um nó raiz que aponta para duas sub-árvores, a da esquerda e a da direita. folha filho folha raiz filho folha É um grafo acíclico dirigido cujos nós tem grau zero, um ou dois Observar que a definição é recursiva! 17 Árvores de busca binária Linda Carla Norton André Mário Xavier Percurso em ordem: André, Carla, Linda, Mário, Norton, Xavier Quantas nós devem ser visitados para se encontrar Xavier? Xavier < Linda? Não, então busque na sub-árvore direita Xavier < Norton? Não, então busque na sub-árvore direita Xavier (3 nós) 18 9
Exercício classificação 1: travessia de árvore binária Faça um algoritmo recursivo que permita percorrer uma árvore de classificação binária em ordem crescente ou decrescente segundo um argumento passado na linha de comando. Dicas Criar uma classe Nodo Um nodo aponta para o nodo da esquerda e da direita 19 Exercício classificação 2: Busca de um nodo em árvore binária Faça um algoritmo recursivo que permita buscar um certo nodo numa árvore de classificação binária por valor. Exemplo: Buscar nodo cujo nome seja Clara Se o nodo buscado não existir, retornar null 20 10
Exercício gramática Fazer um analisador de expressões artiméticas utilizando a grámática recursiva abaixo Gramática exp := exp + termo exp termo termo termo := termo * num termo / num num num := 0 1 2 3 4 5 6 7 8 9 21 Exemplo 1 2 + 3*5 é válida segundo a gramática? exp exp + termo num 2 termo num 3 termo * num 5 sim 22 11
Exemplo 2 5 + -5 é válida segundo a gramática? exp termo exp + termo Não é possível gerar -5 com esta gramática a partir de um termo num 5 não 23 12