1 of 29

Recursividade

2 of 29

  • Se um problema pode ser resolvido facilmente,
    • resolva o problema;
  • Se o problema é grande,
    • elabore uma solução menor do problema,
    • relacione com o problema maior,
    • resolva o problema menor,
    • volte ao problema inicial.

Motivação

3 of 29

  • Um objeto é dito recursivo se ele consistir parcialmente ou for definido em termos de si mesmo.

  • Uma função recursiva é uma função que faz uma chamada a si mesma.

Definição

4 of 29

Recursão Direta ou Indireta

  • Se uma função A contiver uma chamada explícita a si mesma, essa função é dita diretamente recursiva.

A → A

  • Se uma função A contiver uma chamada a uma função B, que por sua vez contenha uma chamada a função A, a função A é dita indiretamente recursiva.

A → B

B → A

5 of 29

  • Todo problema recursivo deve ter
    • Um caso base que pode ser resolvido diretamente;
    • Um passo recursivo que envolve um problema menor.
  • Caso base interrompe a recursão.
  • Passos recursivos devem caminhar para caso base.

Recursão

6 of 29

Um exemplo

  • Fatorial de um número.

1! = 1

2! = 2 * 1

3! = 3 * 2 *1

4! = 4 * 3 * 2 * 1

5! = 5 * 4 * 3 * 2 * 1

5!

5 * 4!

4 * 3!

3 * 2!

2 * 1!

1

7 of 29

Função recursiva

  • Dado um problema:

    • Subdivide este problema em problemas menores (mais simples) e chama a mesma função para resolvê-lo.

    • Para de subdividir quando chega em um problema trivial.

8 of 29

Voltando ao exemplo

5!

5 * 4!

4 * 3!

3 * 2!

2 * 1!

1

2 * 1 = 2

3 * 2 = 6

4 * 6 = 24

5 * 24 = 120

1

Valor Final = 120

9 of 29

Função Fatorial Recursiva

  • Dado o problema do fatorial de um número:

n! = n * (n – 1)! para n>1

1! = 1

0! = 1

10 of 29

Implementando em Python

1 def fatorial(n):

2 if (n == 1) or (n == 0):

3 return 1

4 else:

5 return n * fatorial(n-1)

6 print(fatorial(5))

11 of 29

Chamadas recursivas

fat = fatorial(5)

return 5 * fatorial(4)

return 4 * fatorial(3)

return 3 * fatorial(2)

return 2 * fatorial(1)

return 1

12 of 29

Chamadas recursivas

return 5 * fatorial(4)

return 4 * fatorial(3)

return 3 * fatorial(2)

return 2 * 1

fat = fatorial(5)

13 of 29

Chamadas recursivas

return 5 * fatorial(4)

return 4 * fatorial(3)

return 3 * 2

fat = fatorial(5)

14 of 29

Chamadas recursivas

return 5 * fatorial(4)

return 4 * 6

fat = fatorial(5)

15 of 29

Chamadas recursivas

return 5 * 24

fat = fatorial(5)

16 of 29

Chamadas recursivas

fat = 120

fat = fatorial(5)

17 of 29

Teste de mesa da chamada recursiva

Linha

n

Chamada da função

Saída

6

?

Fat(5) – 1ª chamada

120

Linha

n

Chamada da função

Retorno

1

5

-

5

5

5* Fat(4) – 2ª chamada

120

Linha

n

Chamada da função

Retorno

1

4

-

5

4

4* Fat(3) – 3ª chamada

24

Linha

n

Chamada da função

Retorno

1

3

-

5

3

3* Fat(2) – 4ª chamada

6

Linha

n

Chamada da função

Retorno

1

2

-

5

2

2* Fat(1) – 5ª chamada

2

Linha

n

Chamada da função

Retorno

1

1

-

3

1

-

1

Main

Fat(5)

Fat(4)

Fat(3)

Fat(2)

Fat(1)

18 of 29

Exemplo

  • Escreva uma função que recebe como parâmetro um inteiro positivo n e retorna a soma de todos os números inteiros entre 1 e n.

  • n = 1 → soma(1) = 1
  • n = 2 → soma(2) = 2 + soma(1)
  • n = 3 → soma(3) = 3 + soma(2)

Genericamente: soma(n) = n + soma(n-1)

Caso base: soma(1) = 1

19 of 29

  • Solução Recursiva:

def soma(n):

if (n == 1):

return 1

else:

return n + soma(n - 1)

Exemplo

20 of 29

  • Chamada inicial para a função recursiva :

Exemplo

n = int(input("Qual o valor de n? "))

print ("O somatorio de 0 a %d :" % n)

print ("%d" % soma(n))

21 of 29

Exemplo

  • Série de Fibonacci

22 of 29

Exemplo

def fibonacci(n):

if (n == 0) or (n == 1):

return n

else:

return fibonacci(n-1) + fibonacci(n-2)

23 of 29

fibonacci(4):

4

3

2

1

1

1

1

+

2

fibonacci(4): 3

0

+

0

1

+

1

2

1

0

+

0

1

3

24 of 29

fibonacci(4):

4

3

2

1

+

fibonacci(4): 3

0

+

1

+

2

1

0

+

1

0

1

1

2

1

0

1

3

25 of 29

  • É melhor não usar recursão:
    • Quando as chamadas recursivas acontecem apenas no início ou apenas no fim da função
      • Motivo: cada chamada recursiva reserva memória para as variáveis locais e parâmetros
      • Exemplos: as funções somatório e fatorial
    • Quando o número de tarefas/cálculos repetidos é muito grande, a execução de um programa pode ficar inviável
      • Motivo: em geral, cada chamada recursiva é independente da outra; se duas chamadas recursivas realizam os mesmos cálculos, esses cálculos serão repetidos
      • Exemplo: a função recursiva para a série de Fibonacci

Recursão

26 of 29

Usando Depuração com Funções Recursivas

27 of 29

Usando Depuração com Funções Recursivas

28 of 29

Usando Depuração com Funções Recursivas

29 of 29

  1. Escreva um programa que contenha uma função recursiva que calcule be, em que b e e são números inteiros positivos.
  2. O produto entre dois números inteiros sempre pode ser calculado utilizando-se apenas o operador de adição.

Assim: 2 * 3 = 2 + 2 + 2

Ou seja: x * y = x + x + ...+ x (y vezes)

Escreva uma função recursiva para o cálculo do produto de dois números, usando apenas o operador de soma.

  1. Escreva um programa que contenha uma função recursiva que receba um número natural n, e devolva a soma dos n primeiros números naturais ímpares.
  2. Escreva um programa que leia dois números inteiros e divida um pelo outro, considerando sempre quociente e resto inteiros. A função deve retornar o valor do quociente, desprezando o resto.

Exercícios