Você está na página 1de 77

Algoritmos e estrutura de dados

Aula 3: Recursão
Universidade Federal do Triângulo Mineiro

Professor Me. Rooney R. A. Coelho


30 de Agosto de 2017
Roteiro da Apresentação

1 Recursão
O que é recursão?
Dividir para conquistar
Algoritmos recursivos vs Algoritmos iterativos

2 Exemplos
Exemplo: sequência de Fibonacci
Exemplo: Backtracking
Próximo Tópico

1 Recursão
O que é recursão?
Dividir para conquistar
Algoritmos recursivos vs Algoritmos iterativos

2 Exemplos
Exemplo: sequência de Fibonacci
Exemplo: Backtracking

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 3 / 40


Efeito Droste
O que é?
uma imagem que aparece dentro dela mesma, em um local semelhante
ao da primeira imagem. Uma versão menor, que contém uma versão
menor que a outra, que contém outra menor ainda, e assim por diante.
A imagem foi feita em 1904 e mantida por décadas.

Figura : Caixa do cacau em pó Droste, gênese do “efeito Droste”.


Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 4 / 40
Efeito Droste
Em outras palavras
Um tipo de repetição de um objeto dentro dele mesmo. O objeto está
parcialmente definido dentro dele mesmo.

Figura : Caixa do cacau em pó Droste, gênese do “efeito Droste”.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 5 / 40


Figura : Bonecas Russas (Matryoshka).

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 6 / 40


Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 7 / 40
Como entender recursão?

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 8 / 40


Recursão e matemática

• A recursão está relacionada à indução matemática, com todo o seu


formalismo.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 9 / 40


Recursão e matemática

• A recursão está relacionada à indução matemática, com todo o seu


formalismo.
• A implementação de um algoritmo recursivo em uma linguagem
de programação, partindo de uma definição matemática
também recursiva, é praticamente direta e imediata.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 9 / 40


Recursão e matemática

• A recursão está relacionada à indução matemática, com todo o seu


formalismo.
• A implementação de um algoritmo recursivo em uma linguagem
de programação, partindo de uma definição matemática
também recursiva, é praticamente direta e imediata.
• Por essa razão, esse tipo de algoritmo recursivo possui código
muito mais legível e compacto.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 9 / 40


Recursão e matemática

• A recursão está relacionada à indução matemática, com todo o seu


formalismo.
• A implementação de um algoritmo recursivo em uma linguagem
de programação, partindo de uma definição matemática
também recursiva, é praticamente direta e imediata.
• Por essa razão, esse tipo de algoritmo recursivo possui código
muito mais legível e compacto.

 1 , se n = 0

2n =
2 · 2n−1 , se n ≥ 1

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 9 / 40


Recursão e matemática

 1 , se n = 0

2n =
2 · 2n−1 , se n ≥ 1

int pot2( int n ){


if ( n==0 )
return 1; // Caso base, criterio de parada.
else
return 2 * pot2(n-1); // Caso recursivo.
}

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 10 / 40


Próximo Tópico

1 Recursão
O que é recursão?
Dividir para conquistar
Algoritmos recursivos vs Algoritmos iterativos

2 Exemplos
Exemplo: sequência de Fibonacci
Exemplo: Backtracking

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 11 / 40


Dividir para conquistar

Motivação
O grande potencial da recursão está na possibilidade de poder definir
elementos com base em versões mais simples desses mesmos
elementos.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 12 / 40


Dividir para conquistar

Motivação
O grande potencial da recursão está na possibilidade de poder definir
elementos com base em versões mais simples desses mesmos
elementos.

Ou seja
Em termos computacionais, trata-se de dividir um problema maior em
problemas menores, em que a resolução é feita por uma mesma função,
que é recorrentemente chamada.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 12 / 40


Dividir para conquistar

Motivação
O grande potencial da recursão está na possibilidade de poder definir
elementos com base em versões mais simples desses mesmos
elementos.

Ou seja
Em termos computacionais, trata-se de dividir um problema maior em
problemas menores, em que a resolução é feita por uma mesma função,
que é recorrentemente chamada.

Muitos autores chamam essa técnica computacional de “dividir para


conquistar”, parafraseando o grande imperador francês Napoleão
Bonaparte.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 12 / 40


Dividir para conquistar

Para implementar uma função recursiva, é necessário estabelecer pelo


menos dois elementos:

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 13 / 40


Dividir para conquistar

Para implementar uma função recursiva, é necessário estabelecer pelo


menos dois elementos:
• Uma condição de parada ou terminação. Geralmente, essa
condição estabelece uma solução trivial ou um evento que
encerra a autochamada consecutiva;

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 13 / 40


Dividir para conquistar

Para implementar uma função recursiva, é necessário estabelecer pelo


menos dois elementos:
• Uma condição de parada ou terminação. Geralmente, essa
condição estabelece uma solução trivial ou um evento que
encerra a autochamada consecutiva;
• Uma mudança de estado a cada chamada, ou seja, o
estabelecimento de alguma diferença entre o estado inicial e o
próximo estado da função. Isso pode ser feito, por exemplo,
decrementando um parâmetro da função recursiva.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 13 / 40


Dividir para conquistar

Em resumo, a ideia básica da filosofia dividir para conquistar é:

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 14 / 40


Dividir para conquistar

Em resumo, a ideia básica da filosofia dividir para conquistar é:


1 Divide-se um problema maior em um conjunto de problemas
menores.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 14 / 40


Dividir para conquistar

Em resumo, a ideia básica da filosofia dividir para conquistar é:


1 Divide-se um problema maior em um conjunto de problemas
menores.
2 Esses problemas menores são então resolvidos de forma
independente.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 14 / 40


Dividir para conquistar

Em resumo, a ideia básica da filosofia dividir para conquistar é:


1 Divide-se um problema maior em um conjunto de problemas
menores.
2 Esses problemas menores são então resolvidos de forma
independente.
3 As soluções dos problemas menores são combinadas para gerar a
solução final.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 14 / 40


Dividir para conquistar

1 , se n = 0


n! =
n · (n − 1)!, se n ≥ 1

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 15 / 40


Dividir para conquistar

1 , se n = 0


n! =
n · (n − 1)!, se n ≥ 1

int fatorial ( int n ){


if ( n == 0 )
return 1; // Caso base, criterio de parada.
else
return n * fatorial(n-1); // Caso recursivo.
}

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 15 / 40


Recursão
Importante
Quando a função recursiva chega ao seu caso-base, ela para. Pode-se
chamar a ida ao caso base como caminho de ida da recursão. Após o
algoritmo alcançar o caso base, há o caminho de volta da recursão.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 16 / 40


Recursão
Importante
Quando a função recursiva chega ao seu caso-base, ela para. Pode-se
chamar a ida ao caso base como caminho de ida da recursão. Após o
algoritmo alcançar o caso base, há o caminho de volta da recursão.

4! = 4 * 3! Ida
3! = 3 * 2!
2! = 2 * 1!
1! = 1 * 0!
0! = 1
1! = 1 * 1
2! = 2 * 1
3! = 3 * 2!
4! = 4 * 6 = 24 Volta

Figura : Ilustração do cálculo recursivo do fatorial.


Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 16 / 40
Recursão

1 Sempre que fazemos uma chamada de função o código


atualmente em execução é pausado, e a função chamada é
carregada na memória.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 17 / 40


Recursão

1 Sempre que fazemos uma chamada de função o código


atualmente em execução é pausado, e a função chamada é
carregada na memória.
2 A função main() é pausada quando chama a função fatorial().

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 17 / 40


Recursão

1 Sempre que fazemos uma chamada de função o código


atualmente em execução é pausado, e a função chamada é
carregada na memória.
2 A função main() é pausada quando chama a função fatorial().
3 A função fatorial() também chama a si própria. Nesse caso, ela é
pausada e carrega na memória uma cópia de si mesma, mas
com valor de parâmetro diferente (n − 1).

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 17 / 40


Recursão

1 Sempre que fazemos uma chamada de função o código


atualmente em execução é pausado, e a função chamada é
carregada na memória.
2 A função main() é pausada quando chama a função fatorial().
3 A função fatorial() também chama a si própria. Nesse caso, ela é
pausada e carrega na memória uma cópia de si mesma, mas
com valor de parâmetro diferente (n − 1).
4 O processo se repete até que a função seja chamada com o valor
de n igual a 0, que é o caso base.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 17 / 40


Recursão

fatorial(0)
fatorial(1) fatorial(0)
MEMÓRIA

fatorial(2) fatorial(1) fatorial(1)


fatorial(3) fatorial(2) fatorial(2) fatorial(2)
fatorial(4) fatorial(3) fatorial(3) fatorial(3) fatorial(3)
fatorial(4) fatorial(4) fatorial(4) fatorial(4) fatorial(4)
main() main() main() main() main() main()

CHAMADA DA FUNÇÃO

Figura : Ilustração do uso da memória no caminho de ida da recursão.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 18 / 40


Recursão
Uma vez que se chega ao caso base, faz-se o caminho de volta da
recursão.
Sempre que uma função termina de executar, ela devolve seu resultado
para quem a chamou e, em seguida, é removida da memória.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 19 / 40


Recursão
Uma vez que se chega ao caso base, faz-se o caminho de volta da
recursão.
Sempre que uma função termina de executar, ela devolve seu resultado
para quem a chamou e, em seguida, é removida da memória.

return 1 return
1*fatorial(0) return
1*1 2*fatorial(1)
MEMÓRIA

fatorial(1) return
2*1*1
3*fatorial(2)
fatorial(2) fatorial(2) return
3*2*1*1
4*fatorial(3)
fatorial(3) fatorial(3) fatorial(3) 4*3*2*1*1
fatorial(4) fatorial(4) fatorial(4) fatorial(4)
main() main() main() main() main()

RETORNO DA FUNÇÃO
Figura : Ilustração do uso da memória no caminho de volta da recursão.
Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 19 / 40
Recursão
Em funções recursivas duas coisas devem ficar bem estabelecidas: o
critério de parada e o parâmetro da chamada recursiva.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 20 / 40


Recursão
Em funções recursivas duas coisas devem ficar bem estabelecidas: o
critério de parada e o parâmetro da chamada recursiva.
Critério de parada
Determina quando a função deve parar de chamar a si mesma. Se ele
não existir, a função continuará executando até esgotar a memória do
computador.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 20 / 40


Recursão
Em funções recursivas duas coisas devem ficar bem estabelecidas: o
critério de parada e o parâmetro da chamada recursiva.
Critério de parada
Determina quando a função deve parar de chamar a si mesma. Se ele
não existir, a função continuará executando até esgotar a memória do
computador.

Parâmetro da chamada recursiva


Se refere à mudança do parâmetro passado quando na chamada da
função dentro dela mesma, deve-se sempre mudar o parâmetro passado
para que a recursão chegue a um término.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 20 / 40


Recursão
Em funções recursivas duas coisas devem ficar bem estabelecidas: o
critério de parada e o parâmetro da chamada recursiva.
Critério de parada
Determina quando a função deve parar de chamar a si mesma. Se ele
não existir, a função continuará executando até esgotar a memória do
computador.

Parâmetro da chamada recursiva


Se refere à mudança do parâmetro passado quando na chamada da
função dentro dela mesma, deve-se sempre mudar o parâmetro passado
para que a recursão chegue a um término.

Cuidado
Se o valor do parâmetro for sempre o mesmo, a função continuará
executando até esgotar a memória do computador.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 20 / 40


Recursão

Figura : Ilustração do algoritmo fatorial recursivo.


Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 21 / 40
Próximo Tópico

1 Recursão
O que é recursão?
Dividir para conquistar
Algoritmos recursivos vs Algoritmos iterativos

2 Exemplos
Exemplo: sequência de Fibonacci
Exemplo: Backtracking

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 22 / 40


Algoritmos recursivos vs Algoritmos iterativos
Motivação
A implementação recursiva, na maioria dos casos, é mais simples que a
versão iterativa. Porém, não existe nenhuma razão determinante para
preferir a versão recursiva à iterativa.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 23 / 40


Algoritmos recursivos vs Algoritmos iterativos
Motivação
A implementação recursiva, na maioria dos casos, é mais simples que a
versão iterativa. Porém, não existe nenhuma razão determinante para
preferir a versão recursiva à iterativa.

Ponto negativo
Em muitos casos, as versões recursivas consomem maior número de
recursos (principalmente memória e processamento) e são muito
mais difíceis de testar quando há muitas chamadas.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 23 / 40


Algoritmos recursivos vs Algoritmos iterativos
Motivação
A implementação recursiva, na maioria dos casos, é mais simples que a
versão iterativa. Porém, não existe nenhuma razão determinante para
preferir a versão recursiva à iterativa.

Ponto negativo
Em muitos casos, as versões recursivas consomem maior número de
recursos (principalmente memória e processamento) e são muito
mais difíceis de testar quando há muitas chamadas.

Ponto positivo
A obtenção de códigos mais “enxutos” e mais fáceis de
compreender, mais fáceis de implementar em linguagens de
programação.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 23 / 40


Algoritmos recursivos vs Algoritmos iterativos

Iteração Recursão
estrutura de repetição estrutura de seleção
repetição explícita chamadas repetidas de funções
condição se tornar falsa caso básico é reconhecido
loop infinito não chegar no caso básico

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 24 / 40


Algoritmos recursivos vs Algoritmos iterativos

Iteração Recursão
estrutura de repetição estrutura de seleção
repetição explícita chamadas repetidas de funções
condição se tornar falsa caso básico é reconhecido
loop infinito não chegar no caso básico

Cuidado!
A recursão ativa repetidamente o mecanismo de chamadas de funções,
o que pode custar caro tanto em termos de tempo de processamento
como em alocação de memória.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 24 / 40


Algoritmos recursivos vs Algoritmos iterativos

Você deve utilizar a recursão quando:

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 25 / 40


Algoritmos recursivos vs Algoritmos iterativos

Você deve utilizar a recursão quando:


1 O problema é naturalmente recursivo (clareza) e a versão recursiva
do algoritmo não gera ineficiência evidente, se comparada com a
versão iterativa;

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 25 / 40


Algoritmos recursivos vs Algoritmos iterativos

Você deve utilizar a recursão quando:


1 O problema é naturalmente recursivo (clareza) e a versão recursiva
do algoritmo não gera ineficiência evidente, se comparada com a
versão iterativa;
2 O algoritmo se torna compacto, sem perda de clareza ou
generalidade;

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 25 / 40


Algoritmos recursivos vs Algoritmos iterativos

Você deve utilizar a recursão quando:


1 O problema é naturalmente recursivo (clareza) e a versão recursiva
do algoritmo não gera ineficiência evidente, se comparada com a
versão iterativa;
2 O algoritmo se torna compacto, sem perda de clareza ou
generalidade;
3 É possível prever que o número de chamadas não vai provocar
interrupção no processo.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 25 / 40


Algoritmos recursivos vs Algoritmos iterativos

Você não deve utilizar a recursão quando:

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 26 / 40


Algoritmos recursivos vs Algoritmos iterativos

Você não deve utilizar a recursão quando:


1 A solução recursiva causa ineficiência, se comparada com a versão
iterativa;

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 26 / 40


Algoritmos recursivos vs Algoritmos iterativos

Você não deve utilizar a recursão quando:


1 A solução recursiva causa ineficiência, se comparada com a versão
iterativa;
2 Existe uma única chamada da função recursiva no fim ou no
começo da rotina, com a função podendo ser transformado numa
iteração simples;

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 26 / 40


Algoritmos recursivos vs Algoritmos iterativos

Você não deve utilizar a recursão quando:


1 A solução recursiva causa ineficiência, se comparada com a versão
iterativa;
2 Existe uma única chamada da função recursiva no fim ou no
começo da rotina, com a função podendo ser transformado numa
iteração simples;
3 O uso de recursão acarreta número maior de cálculos que a versão
iterativa;

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 26 / 40


Algoritmos recursivos vs Algoritmos iterativos

Você não deve utilizar a recursão quando:


1 A solução recursiva causa ineficiência, se comparada com a versão
iterativa;
2 Existe uma única chamada da função recursiva no fim ou no
começo da rotina, com a função podendo ser transformado numa
iteração simples;
3 O uso de recursão acarreta número maior de cálculos que a versão
iterativa;
4 A recursão é de cauda;

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 26 / 40


Algoritmos recursivos vs Algoritmos iterativos

Você não deve utilizar a recursão quando:


1 A solução recursiva causa ineficiência, se comparada com a versão
iterativa;
2 Existe uma única chamada da função recursiva no fim ou no
começo da rotina, com a função podendo ser transformado numa
iteração simples;
3 O uso de recursão acarreta número maior de cálculos que a versão
iterativa;
4 A recursão é de cauda;
5 Parâmetros consideravelmente grandes têm que ser passados por
valor;

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 26 / 40


Algoritmos recursivos vs Algoritmos iterativos

Você não deve utilizar a recursão quando:


1 A solução recursiva causa ineficiência, se comparada com a versão
iterativa;
2 Existe uma única chamada da função recursiva no fim ou no
começo da rotina, com a função podendo ser transformado numa
iteração simples;
3 O uso de recursão acarreta número maior de cálculos que a versão
iterativa;
4 A recursão é de cauda;
5 Parâmetros consideravelmente grandes têm que ser passados por
valor;
6 Não é possível prever o número de chamadas da função, podendo
assim causar sobrecarga.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 26 / 40


Recursão de cauda
O que é?
É aquela que faz a chamada dos casos recursivos no final da função,
após testar ou apresentar o n-ésimo valor. Em outras palavras, as
funções recursivas em cauda são as que a chamada recursiva é a
última instrução a ser executada. Ou seja, não existe processamento
a ser feito depois de encerrada a chamada recursiva.

Algoritmos com recursão de cauda


O cálculo do fatorial, a sequencia de Fibonacci, a soma de vetores são
exemplos de recursão de cauda.

Algoritmos sem recursão de cauda


Algoritmos como busca binária e a permutação não utilizam recursão
de cauda.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 27 / 40


Próximo Tópico

1 Recursão
O que é recursão?
Dividir para conquistar
Algoritmos recursivos vs Algoritmos iterativos

2 Exemplos
Exemplo: sequência de Fibonacci
Exemplo: Backtracking

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 28 / 40


Sequência de Fibonacci

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...

Definição
Cada termo subsequente
corresponde à soma dos dois
termos precedentes.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 29 / 40


Sequência de Fibonacci
0, se n = 0


F (n) = 1, se n = 1
F (n − 1) + F (n − 2), se n > 1

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 30 / 40


Sequência de Fibonacci
0, se n = 0


F (n) = 1, se n = 1
F (n − 1) + F (n − 2), se n > 1

int fibo(int n){


if( n == 0 || n == 1 )
return n;
else
return fibo(n-1) + fibo(n-2);
}

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 30 / 40


Sequência de Fibonacci
0, se n = 0


F (n) = 1, se n = 1
F (n − 1) + F (n − 2), se n > 1

int fibo(int n){


if( n == 0 || n == 1 )
return n;
else
return fibo(n-1) + fibo(n-2);
}

Cuidado!
a solução recursiva para a sequência de Fibonacci é muito elegante.
Infelizmente, ela contém duas chamadas para si mesma. Isso
significa que ela contém duas chamadas recursivas. Logo, sua
elegância não significa eficiência.
Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 30 / 40
Sequência de Fibonacci

2 1
fibo(4)

1 1 1 0
fibo(3) fibo(2)

1 0
fibo(2) fibo(1) fibo(1) fibo(0)

fibo(1) fibo(0)

Figura : Ilustração do algoritmo Fibonacci recursivo para n = 4.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 31 / 40


Sequência de Fibonacci

3 2
fibo(5)

2 1 1 1
fibo(4) fibo(3)

1 1 1 0 1 0
fibo(3) fibo(2) fibo(2) fibo(1)

1 0
fibo(2) fibo(1) fibo(1) fibo(0) fibo(1) fibo(0)

fibo(1) fibo(0)

Figura : Ilustração do algoritmo Fibonacci recursivo para n = 5.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 32 / 40


Razão aurea
Como calcular a seguinte função no computador?
1
φ=1+ 1
1+ 1+ 1
1+ 1
1+ 1
1+ 1
1+ 1
1+ 1
1
1+ ...

φ = 1.6180339887498948482...

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 33 / 40


Razão aurea
Como calcular a seguinte função no computador?
1
φ=1+ 1
1+ 1+ 1
1+ 1
1+ 1
1+ 1
1+ 1
1+ 1
1
1+ ...

φ = 1.6180339887498948482...

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 33 / 40


Razão aurea

Como calcular a seguinte função no computador?


1
φ=1+ 1
1+ 1+ 1
1+ 1
1+ 1
1+ 1
1+ 1
1+ 1
1
1+ ...

φ = 1.6180339887498948482...

Solução recursiva!

φ = 1 + 1/φ

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 34 / 40


Razão aurea

Vamos ao código!

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 35 / 40


Próximo Tópico

1 Recursão
O que é recursão?
Dividir para conquistar
Algoritmos recursivos vs Algoritmos iterativos

2 Exemplos
Exemplo: sequência de Fibonacci
Exemplo: Backtracking

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 36 / 40


Backtracking

O que é?
Backtracking refere-se a um tipo de algoritmo para encontrar todas (ou
algumas) soluções de um problema computacional, que
incrementalmente constrói candidatas de soluções e abandona
uma candidata parcialmente construída tão logo quanto for
possível determinar que ela não pode gerar uma solução válida.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 37 / 40


Backtracking

O que é?
Backtracking refere-se a um tipo de algoritmo para encontrar todas (ou
algumas) soluções de um problema computacional, que
incrementalmente constrói candidatas de soluções e abandona
uma candidata parcialmente construída tão logo quanto for
possível determinar que ela não pode gerar uma solução válida.

Quando aplicável
Frequentemente muito mais rápido que algoritmos de enumeração
total (força bruta), já que ele pode eliminar um grande número de
soluções inválidas com um único teste. Gera apenas soluções
válidas.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 37 / 40


Backtracking: Labirinto
Baseado no programa do prof. Zanoni Dias da Unicamp
• Dado um labirinto representado por uma matriz de tamanho
n × m, uma posição inicial pi = (xi , yi ) e uma posição final
pf = (xf , yf ), tal que pi 6= pf , determinar se existe um caminho
entre pi e pf .

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 38 / 40


Backtracking: Labirinto
Baseado no programa do prof. Zanoni Dias da Unicamp
• Dado um labirinto representado por uma matriz de tamanho
n × m, uma posição inicial pi = (xi , yi ) e uma posição final
pf = (xf , yf ), tal que pi 6= pf , determinar se existe um caminho
entre pi e pf .
• Podemos representar o labirinto como uma matriz M tal que:

 −2, se a posição representa uma parede


M[x, y] = −1, se a posição não pertence ao caminho


i, tal que a posição pertence ao caminho

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 38 / 40


Backtracking: Labirinto
Baseado no programa do prof. Zanoni Dias da Unicamp
• Dado um labirinto representado por uma matriz de tamanho
n × m, uma posição inicial pi = (xi , yi ) e uma posição final
pf = (xf , yf ), tal que pi 6= pf , determinar se existe um caminho
entre pi e pf .
• Podemos representar o labirinto como uma matriz M tal que:

 −2, se a posição representa uma parede


M[x, y] = −1, se a posição não pertence ao caminho


i, tal que a posição pertence ao caminho

• Neste caso, vamos supor que o labirinto é cercado por paredes,


eventualmente apenas com exceção do local designado como
saída.

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 38 / 40


Backtracking: Labirinto

Vamos ao código!

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 39 / 40


Obrigado!

Professor Me. Rooney R. A. Coelho (UFTM) Aula 3 30 de Agosto de 2017 40 / 40