Vous êtes sur la page 1sur 18

Lgica de Programao Recursividade

Regis Pires Magalhes


regis@cefetpi.br
ltima atualizao em 07/08/2008

Recursividade
Um algoritmo que para resolver um problema divide-o em subprogramas mais simples, cujas solues requerem a aplicao dele mesmo, chamado recursivo, seja de forma direta ou indireta. Em geral, uma rotina recursiva R pode ser expressa como uma composio formada por um conjunto de comandos C (que no contm chamadas a R) e uma chamada (recursiva) rotina R:
Recurso Direta

Exemplo
Fatorial
A definio 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 verificvel) dos fatoriais que:
n! = n * (n-1)!

Esta propriedade chamada de propriedade recursiva: o fatorial de um numero pode ser calculado atravs 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

Caso base ou Condio de Parada


Como uma funo recursiva pode chamar a si mesma indefinidamente, essencial a existncia do caso base, ou condio de parada.

Forma geral
Esquematicamente, os algoritmos recursivos tm 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

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 direo ao caso de base, seno o algoritmo no 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

Exemplo
algoritmo "fatorial" var numero: inteiro funcao fat (n:Inteiro):Inteiro inicio se n=0 entao retorne 1 senao retorne n * Fat (n-1) fimse fimfuncao inicio escreva("Digite um nmero: ") leia (numero) escreval("O fatorial de ", numero, " ", fat(numero)) fimalgoritmo

Exemplo no recursivo
algoritmo "fatorial" var numero: inteiro funcao fat (n:Inteiro):Inteiro var i, resultado : inteiro inicio resultado <- 1 para i de n ate 1 passo -1 faca resultado <- resultado * i fimpara retorne resultado fimfuncao inicio escreva("Digite um nmero: ") leia (numero) escreval("O fatorial de ", numero, " ", fat(numero)) fimalgoritmo

Algoritmos Recursivos x Iterativos


Todo algoritmo recursivo possui um algoritmo iterativo equivalente, mudando apenas a sua complexidade de construo. Vantagens
Simplifica a soluo de alguns problemas Algoritmos recursivos so mais compactos para alguns tipos de algoritmo, mais legveis e mais fceis de ser compreendidos e implementados.

Desvantagens
Por usarem intensivamente a pilha de execuo, os algoritmos recursivos tendem a ser mais lentos e a consumir mais memria que os iterativos, porm pode valer a pena sacrificar a eficincia em benefcio da clareza. Erros de implementao podem levar a estouro de pilha. Isto , caso no seja indicada uma condio de parada, ou se esta condio nunca for satisfeita, entre outros.

Recurso Indireta
Entretanto, pode-se ter tambm uma forma indireta de recurso, na qual as rotinas so conectadas atravs de uma cadeia de chamadas recursivas que acaba retornando a primeira que foi chamada:

Torres de Hani

Quebra-cabeas com uma base de 3 pinos, onde num deles, so dispostos discos uns sobre os outros, em ordem crescente de dimetro, 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 situao. O nmero de discos pode variar, sendo que o mais simples contm apenas trs.

A Lenda
"No grande templo de Benares, embaixo da cpula que marca o centro do mundo, repousa uma placa de lato onde esto presas trs agulhas de diamante, cada uma com 50 cm de altura e com espessura do corpo de uma abelha. Em uma dessas agulhas, durante a criao, Deus colocou sessenta e quatro discos de ouro puro, com o disco maior repousando sobre a placa de lato 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 imutveis de Brahma, que exigem que o sacerdote em viglia no mova mais de um disco por vez e que ele coloque este disco em uma agulha de modo que no haja nenhum disco menor embaixo dele. Quando os sessenta e quatro discos tiverem sido assim transferidos da agulha em que a criao de Deus as colocou para uma das outras agulhas, a torre, o templo e os brmanes viraro p, e com um trovejar, o mundo desaparecer."

Soluo
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).

Soluo

O nmero mnimo de "movimentos" para conseguir transferir todos os discos 2n-1, sendo n o nmero de discos. Logo:
Para 3 discos , so necessrios 7 movimentos Para 7 discos, so necessrios 127 movimentos Para 15 discos, so necessrios 32.767 movimentos Para 64 discos, como diz a lenda, so necessrios 18.446.744.073.709.551.615 movimentos.

Soluo tima

Soluo Recursiva
A soluo para o problema da Torre de Hanoi com recursividade compacta e baseia-se no seguinte:
A nica operao possvel 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 soluo 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 transferncia da torre de cima no uma operao possvel de ser executada, ela dever ser reduzida sucessivamente at transformar-se em um movimento de disco.

Soluo Recursiva

Algoritmo
algoritmo "hanoi" var num_discos, numero_movimentos : inteiro

procedimento transfere(n : inteiro; origem, destino, auxiliar : caracter) inicio se (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) fimse fimprocedimento
inicio escreva("Digite o nmero de discos: ") leia(num_discos) transfere(num_discos, "A", "C", "B") escreval("Nmero total de movimentos: ", numero_movimentos) fimalgoritmo