O documento introduz o conceito de recursividade em algoritmos e estruturas de dados, definindo-a como uma rotina que chama a si mesma. Apresenta exemplos como o fatorial e explica o controle de chamadas recursivas usando pilha. Também diferencia recursão de iteração e discute aplicações em listas, pilhas e filas.
2. AGENDA
Introdução
Exemplo: Fatorial
Controle de Chamada e Retorno de Rotinas Recursivas
Iteração X Recursão
Exemplo: Fatorial
Recursão de Cauda
Recursividade em Listas, Pilhas e Filas
07/12/2016
2
3. INTRODUÇÃO
Uma rotina (procedimento ou função) que chama a si
mesma, de forma direta ou indireta, é dita RECURSIVA.
LOOPING: ao utilizar recursão deve-se tomar cuidado para
que a rotina não entre em LOOP INFINITO (chamar a si
mesma infinitamente)
TERMINAÇÃO: Uma rotina recursiva deve ser finita, deve
haver uma condição de parada, que termine a rotina.
07/12/2016
3
4. INTRODUÇÃO
A solução para um problema recursivo normalmente pode ser dividida em
duas partes (divisão e conquista): uma em que a solução é simples, e outra em
que a solução é mais difícil.
TRIVIAL: fácil de se resolver e retorna um resultado, geralmente é o caso mais
básico, ou simples, do problema (inclusive, não há necessidade de se aplicar
recursão)
GERAL (NÃO TRIVIAL ou COMPLEXO): Neste caso, o problema é, em sua
essência, igual ao problema original, porém deve ser uma versão mais
genérica, simples, menor. Como esse novo problema é parecido com o
original, a rotina chama uma nova cópia de si mesma para trabalhar no
problema menor.07/12/2016
4
5. INTRODUÇÃO
Chamada Recursiva:
Ocorre enquanto a chamada original para a rotina ainda está ativa.
Inclui uma instrução de retorno que juntará o resultado atual com o
resultado anterior, formando o resultado final que será passado de volta
para quem chamou.
Pode resultar em muitas chamadas, conforme a necessidade da rotina em
dividir o subproblema.
A quebra do problema em problemas menores convergirá para o caso
básico (trivial)
Chegando ao caso trivial, a rotina recursiva retorna um resultado para a
rotina anterior e a sequencia de RETORNOS segue na fila até a chamada
original que retornará o resultado final para quem chamou.
07/12/2016
5
6. INTRODUÇÃO
Recursão Direta: é uma rotina formada por um conjunto de
comandos e uma chamada à rotina. (mesma rotina)
Recursão Indireta: é uma rotina que contém uma chamada a
outra rotina que, por sua vez, tem uma chamada a outra rotina e
assim sucessivamente. (rotinas diferentes)
Melhor uso para quando o problema a ser resolvido é de
natureza recursiva, ou é definido em termos recursivos. Exemplo:
estrutura de árvores.
07/12/2016
6
7. Exemplo: Fatorial
O fatorial de um número natural n, representado por n!, é o produto de todos
os inteiros positivos menores ou iguais a n.
n! = n * ( n – 1 ) * ( n – 2 ) * ( n – 3 ) * ... * 1
Caso Básico Trivial (menor problema): 0! =1 e 1! = 1
Caso Geral (problema complexo): n! = n * ( n -1 )!
Exemplos: 2! = 2 * 1 = 2; 3! = 3 * 2 * 1 = 6; 4! = 4 * 3 * 2 * 1 = 24
07/12/2016
7
9. function fatorial
(n:integer) :
integer;
if n = 0 then
Fatorial := 1;
Else
fatorial := n * fatorial ( n - 1 );
Quando atingir zero, as
chamadas recursivas começam a
retornar
10 N = 0 10 = 0 Fatorial := 10 * fatorial ( 10 – 1 )
Fatorial := 10 * fatorial ( 9 )
10! = 3.628.800
9 N = 0 9 = 0 F Fatorial := 9 * fatorial ( 9 – 1 )
Fatorial := 9 * fatorial ( 8 )
9! = 362.880
8 N = 0 8 = 0 F Fatorial := 8 * fatorial ( 8 – 1 )
Fatorial := 8 * fatorial ( 7 )
8! = 40.320
7 N = 0 7 = 0 F Fatorial := 7 * fatorial ( 7 – 1 )
Fatorial := 7 * fatorial (6)
7! = 5.040
6 N = 0 6 = 0 F Fatorial := 6 * fatorial ( 6 – 1 )
Fatorial := 6 * fatorial (5)
6! = 720
5 N = 0 5 = 0 F Fatorial := 5 * fatorial ( 5 – 1 )
Fatorial := 5 * fatorial ( 4 )
5! = 120
4 N = 0 4 = 0 F Fatorial := 4 * fatorial ( 4 – 1 )
Fatorial := 4 * fatorial (3)
4! = 24
3 N = 0 3 = 0 F Fatorial := 3 * fatorial ( 3 – 1 )
Fatorial := 3 * fatorial ( 2 )
3! = 6
2 N = 0 2 = 0 F Fatorial := 2 * fatorial ( 2 – 1 )
Fatorial := 2 * fatorial ( 1 )
2! = 2
1 N = 0 1 = 0 F Fatorial := 1 * fatorial ( 1 – 1 )
Fatorial := 1 * fatorial (0)
1! = 1
0 N = 0 1 = 0 V
Fatorial := 1;
0! = 1
Primeiro, o
problema é
decomposto de
cima para baixo e,
depois, é
resolvido de baixo
para cima.
07/12/2016
9
10. Controle de chamada e retornos de
rotinas recursivas
Uma rotina recursiva é implementada por meio de uma PILHA.
A PILHA armazena os dados usados em cada chamada da ROTINA que ainda
não terminou de executar.
Quando uma rotina é evocada, são empilhadas todas as suas variáveis locais e
o endereço de retorno.
O estado corrente deve ser registrado para posterior recuperação.
À medida que cada chamada recursiva retorna, os dados da chamada são
removidos e a execução é retomada no ponto da chamada da rotina.
07/12/2016
10
11. Controle de chamada e retornos de rotinas recursivas
10
9
10
8
9
10
Fat (10)
n
n
7
8
9
10
6
7
8
9
10
5
6
7
8
9
10
4
5
6
7
8
9
10
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
n
n
n
n
n
n
n
n
Fat (9) Fat (8) Fat (7) Fat (6) Fat (5) Fat (4) Fat (3) Fat (2)
A cada momento apenas a última variável N criada pode ser acessada!
A rotina retorna para quem chamou utilizando o endereço de retorno que está no
topo da pilha.
Fat (1)
Chamadas na
Pilha de
Execução do
Programa.
A Variável N é
recriada na
pilha a cada
chamada
recursiva
07/12/2016
11
12. ITERAÇÃO X RECURSÃO
Tanto ITERAÇÃO quanto RECURSÃO usam repetição:
Iteração: usa repetição em forma de comandos de
repetição (for, while)
Recursão: usa a repetição na forma de chamadas
repetitivas a uma rotina
07/12/2016
12
13. ITERAÇÃO X RECURSÃO
Ambas precisam de um teste de terminação:
Iteração: termina quando a condição de teste falha
Recursão: termina quando se atinge o caso trivial
07/12/2016
13
14. ITERAÇÃO X RECURSÃO
Ambas podem entrar em loop infinito:
Iteração: se o teste nunca se tornar falso
Recursão: se o problema não for reduzido de forma que
convirja para o caso trivial
07/12/2016
14
15. ITERAÇÃO X RECURSÃO
Uma função que pode ser produzida por um computador,
pode ser escrita como uma função recursiva sem o uso de
iteração.
Reciprocamente, uma função recursiva pode ser descrita
através de iterações sucessivas.
Linguagem de programação funcional e Programação
Lógica.
07/12/2016
15
17. Recursão de Cauda
Quando a chamada recursiva está no final do código da rotina
Tem a função de criar um loop
Exemplo: fatorial := n * fatorial ( n -1 )
A Recursão de cauda é menos eficiente que a Iteração.
No lugar da recursão da cauda, usar iteração.
07/12/2016
17
18. Recursividade em Listas, Pilhas e Filas
Nas estruturas de dados como Listas, Pilhas e Filas também
é possível usar a recursividade
São empregadas nas rotinas de remoção de elementos.
07/12/2016
18
23. Referências
1. Deitel, H. M.; Deitel, P. J. Java: Como Programar. Tradução: Edson Furmankiewicz; Revisão Técnica: Fábio Luis
Picelli Lucchini. 6.ª Edição. São Paulo: Pearson Prentice Hall, 2005. Cap. 15, p. 551-581.
2. Deitel, H. M.; Deitel, P. J. C: Como Programar. Tradução: Daniel Vieira; Revisão Técnica: César Caetano. 6.ª
Edição. São Paulo: Pearson Prentice Hall, 2011. p. 137-145.
3. Deitel, H. M.; Deitel, P. J. C++: Como Programar. Tradução: Edson Furmankiewicz; Revisão Técnica: Fábio Luis
Picelli Lucchini. 5.ª Edição. São Paulo: Pearson Prentice Hall, 2006. p. 221-228.
4. Schildt, H.; Skrien, D. Programação com Java: Uma Introdução Abrangente. Tradução: Aldir José Coelho Cêrrea
da Silva. Revisão Técnica: Maria Lúcia Blanck Lisbôa. Porto Alegre: AMGH, 2013. p. 225-229.
5. Ziviani, N. Projeto de Algoritmos com Implementações em Pascal e C. 3.ª ed. rev. e amp. São Paulo: Cengage
Learning, 2015. p. 40-44.
6. Forouzan, B., Mosharraf, F. Fundamentos da Ciência da Computação. Tradução: Solange Aparecida Visconti.
Revisão Técnica: Ronaldo A. L. Gonçalves. São Paulo: Cengage Learning, 2011. p. 208-210.
7. Pereira, S. L. Estruturas de Dados Fundamentais: Conceitos e Aplicações. São Paulo: Érica, 1996. cap. 13, p. 145-
15607/12/2016
23