18
Lógica de Programação Recursividade Regis Pires Magalhães [email protected] Última atualização em 07/08/2008

Logica Algoritmo 08 Recursividade

Embed Size (px)

Citation preview

Page 1: Logica Algoritmo 08 Recursividade

Lógica de Programação

Recursividade

Regis Pires Magalhã[email protected]

Última atualização em 07/08/2008

Page 2: Logica Algoritmo 08 Recursividade

Recursividade• Um algoritmo que para resolver um problema

divide-o em subprogramas mais simples, cujas soluções requerem a aplicação dele mesmo, é chamado recursivo, seja de forma direta ou indireta.

• Em geral, uma rotina recursiva R pode ser expressa como uma composição formada por um conjunto de comandos C (que não contém chamadas a R) e uma chamada (recursiva) à rotina R:

Recursão Direta

Page 3: Logica Algoritmo 08 Recursividade

Exemplo• Fatorial

– A definição de fatorial é:• F(n) = 1 se n = 0 ou n = 1;• F(n) = n * F(n-1), se n>1.• onde n é um numero inteiro positivo. Uma propriedade

(facilmente verificável) dos fatoriais é que:– n! = n * (n-1)!

– Esta propriedade é chamada de propriedade recursiva: o fatorial de um numero pode ser calculado através do fatorial de seu antecessor.

• F(4) = 4 * F(4-1)• F(3) = 3 * F(3-1)• F(2) = 2 * F(2-1)• F(1) = 1 * F(1-1)• F(0) = 1

Page 4: Logica Algoritmo 08 Recursividade

Caso base ou Condição de Parada

Como uma função recursiva pode chamar a si mesma indefinidamente, é essencial a existência do caso base, ou condição de parada.

Page 5: Logica Algoritmo 08 Recursividade

Forma geral• Esquematicamente, os algoritmos recursivos têm a

seguinte forma:

se "condicao para o caso de base" entao resolucao direta para o caso de base senao uma ou mais chamadas recursivas fimse

Page 6: Logica Algoritmo 08 Recursividade

Caso Base• Um algoritmo recursivo pode ter um ou mais casos

de base e um ou mais casos gerais. • E para que o algoritmo termine, as chamadas

recursivas devem convergir em direção ao caso de base, senão o algoritmo não terminará jamais.

• Convergir significa ter uma parte menor do problema para ser resolvido.

F(4) = 4.F(4-1) F(3) = 3.F(3-1) F(2) = 2.F(2-1) F(1) = 1.F(1-1) F(0) = 1 ------------ Caso Base F(1) = 1.1 F(2) = 2.1 F(3) = 3.2 F(4) = 4.6

Page 7: Logica Algoritmo 08 Recursividade

Exemploalgoritmo "fatorial"varnumero: inteiro

funcao fat (n:Inteiro):Inteiroinicio se n=0 entao retorne 1 senao retorne n * Fat (n-1) fimsefimfuncao

inicio escreva("Digite um número: ") leia (numero) escreval("O fatorial de ", numero, " é ",

fat(numero))fimalgoritmo

Page 8: Logica Algoritmo 08 Recursividade

Exemplo não recursivoalgoritmo "fatorial"varnumero: inteiro

funcao fat (n:Inteiro):Inteirovar i, resultado : inteiroinicio resultado <- 1 para i de n ate 1 passo -1 faca resultado <- resultado * i fimpara retorne resultadofimfuncao

inicio escreva("Digite um número: ") leia (numero) escreval("O fatorial de ", numero, " é ",

fat(numero))fimalgoritmo

Page 9: Logica Algoritmo 08 Recursividade

Algoritmos Recursivos x Iterativos

• Todo algoritmo recursivo possui um algoritmo iterativo equivalente, mudando apenas a sua complexidade de construção.

• Vantagens– Simplifica a solução de alguns problemas

– Algoritmos recursivos são mais compactos para alguns tipos de algoritmo, mais legíveis e mais fáceis de ser compreendidos e implementados.

• Desvantagens– Por usarem intensivamente a pilha de execução, os algoritmos

recursivos tendem a ser mais lentos e a consumir mais memória que os iterativos, porém pode valer a pena sacrificar a eficiência em benefício da clareza.

– Erros de implementação podem levar a estouro de pilha. Isto é, caso não seja indicada uma condição de parada, ou se esta condição nunca for satisfeita, entre outros.

Page 10: Logica Algoritmo 08 Recursividade

Recursão Indireta• Entretanto, pode-se ter também uma forma indireta

de recursão, na qual as rotinas são conectadas através de uma cadeia de chamadas recursivas que acaba retornando a primeira que foi chamada:

Page 11: Logica Algoritmo 08 Recursividade

Torres de Hanói

• Quebra-cabeças com uma base de 3 pinos, onde num deles, são dispostos discos uns sobre os outros, em ordem crescente de diâmetro, de cima para baixo.

• O problema consiste em passar todos os discos de um pino para outro qualquer, usando um dos pinos como auxiliar, de maneira que um disco maior nunca fique em cima de outro menor em nenhuma situação.

• O número de discos pode variar, sendo que o mais simples contém apenas três.

Page 12: Logica Algoritmo 08 Recursividade

A Lenda

• "No grande templo de Benares, embaixo da cúpula que marca o centro do mundo, repousa uma placa de latão onde estão presas três agulhas de diamante, cada uma com 50 cm de altura e com espessura do corpo de uma abelha.

• Em uma dessas agulhas, durante a criação, Deus colocou sessenta e quatro discos de ouro puro, com o disco maior repousando sobre a placa de latão e os outros diminuindo cada vez mais ate o topo.

• Essa é a torre de Brahma. Dia e noite, sem parar, os sacerdotes transferem os discos de uma agulha de diamante para outra de acordo com as leis ficas e imutáveis de Brahma, que exigem que o sacerdote em vigília não mova mais de um disco por vez e que ele coloque este disco em uma agulha de modo que não haja nenhum disco menor embaixo dele.

• Quando os sessenta e quatro discos tiverem sido assim transferidos da agulha em que a criação de Deus as colocou para uma das outras agulhas, a torre, o templo e os brâmanes virarão pó, e com um trovejar, o mundo desaparecerá."

Page 13: Logica Algoritmo 08 Recursividade

Solução• Algoritmo para mover N discos de A para C,

usando B como auxiliar:1. Se N==1, mova o único disco de A para C e pare.2. Se N>1:

1. Mova os N-1 discos superiores de A para B, usando C como auxiliar (passo 2 da figura abaixo).

2. Mova o disco restante de A para C (passo 3 da figura abaixo).3. Mova os N-1 discos de B para C, usando A como auxiliar

(passo 4 da figura abaixo).

Page 14: Logica Algoritmo 08 Recursividade

Solução

Page 15: Logica Algoritmo 08 Recursividade

Solução Ótima• O número mínimo de "movimentos" para

conseguir transferir todos os discos é 2n-1, sendo n o número de discos.

• Logo:– Para 3 discos , são necessários 7 movimentos– Para 7 discos, são necessários 127 movimentos– Para 15 discos, são necessários 32.767 movimentos– Para 64 discos, como diz a lenda, são necessários

18.446.744.073.709.551.615 movimentos.

Page 16: Logica Algoritmo 08 Recursividade

Solução Recursiva• A solução para o problema da Torre de Hanoi com

recursividade é compacta e baseia-se no seguinte:– A única operação possível de ser executada é "move

disco de um pino para outro";– Uma torre com (N) discos, em um pino, pode ser

reduzido ao disco de baixo e a torre de cima com (N-1) discos;

– A solução consiste em transferir a torre com (N-1) discos do pino origem para o pino auxiliar, mover o disco de baixo do pino origem para o pino destino e transferir a torre com (N-1) discos do pino auxiliar para o pino destino. Como a transferência da torre de cima não é uma operação possível de ser executada, ela deverá ser reduzida sucessivamente até transformar-se em um movimento de disco.

Page 17: Logica Algoritmo 08 Recursividade

Solução Recursiva

Page 18: Logica Algoritmo 08 Recursividade

Algoritmoalgoritmo "hanoi"var num_discos, numero_movimentos : inteiro

procedimento transfere(n : inteiro; origem, destino, auxiliar : caracter)iniciose (n = 1) entao numero_movimentos <- numero_movimentos + 1 escreval(numero_movimentos, " - Mova de ", origem, " para ", destino)senao transfere(n-1, origem, auxiliar, destino) numero_movimentos <- numero_movimentos + 1 escreval(numero_movimentos, " - Mova de ", origem, " para ", destino) transfere(n-1, auxiliar, destino, origem)fimsefimprocedimento

inicioescreva("Digite o número de discos: ")leia(num_discos)transfere(num_discos, "A", "C", "B")escreval("Número total de movimentos: ", numero_movimentos)fimalgoritmo