Recursão
A recursão é bastante usada na matemática para definir funções, usando elas mesmas nas suas próprias definições. Por exemplo o cálculo de um fatorial, pode ser representada em forma de recursão da seguinte forma: n!=0 se n = 0 n!=n*(n-1)! se n > 0
Usando a definição acima, o fatorial de um número podemos calcular multiplicando o número pelo fatorial do número inteiro anterior, e por sua vez o fatorial deste número podemos calcular multiplicando ele pelo fatorial de seu antecessor, e assim sucessivamente até chegar a 0, onde o fatorial é igual a 1. Nesse momento acaba a recursão
Existem muitas funções ou procedimentos que podemos definir em forma simples e compacta usando a recursão. Vejamos como podemos usar a recursão em Pascal para calcular o fatorial de um número. Vamos definir a função fatorial(n) que recebe como parâmetro um número inteiro n e retorna o fatorial do número.
function fatorial(n:integer):integer; begin if(n=0) then fatorial:=1 else fatorial:=n*fatorial(n-1); end;
Para testar a função vamos escrever o programa que chama a função fatorial
Program TestaFatorial; Var n, f: integer; function fatorial(n:integer):integer; begin if(n=0) then fatorial:=1 else fatorial:=n*fatorial(n-1); end; Begin writeln('entre com um nmero inteiro'); Readln(n); f:=fatorial(n); writeln('o fatorial de ',n,' eh ',f); End.
Vejamos a aplicação da recursão em um outro problema mais interessante.
Torre de Hanoi As Torres de Hanói são um quebra-cabeca muito antigo e conhecido. Esse quebra-vabeça consiste de um conjunto de N discos de tamanhos diferentes e três pinos verticais, nos quais os discos podem ser encaixados.
Cada pino pode conter uma pilha com qualquer número de discos, desde que cada disco não seja colocado acima de outro disco de menor tamanho. A configuração inicial consiste de todos os discos no pino 1. O objetivo é mover todos os discos para um dos outros discos, sempre obedecendo à restrição de não colocar um disco sobre outro menor.
Tarefa Escrever um programa que determine quantos movimentos de trocar um disco de um pino para outro serão necessários para levar todos os disco do pino 1 (origem) para o pino 3 (destino). Como entrada o programa recebe o número de discos.
Este problema vamos resolver analisando varias situações da seguinte forma: Primeiro vamos analisar a situação mais simples: o que fazemos se temos apenas um disco?. A resposta é levar o disco do origem ao destino, neste caso o número de movimentos é 1.
Agora vamos analisar a situação em que temos 2 discos (N=2) no origem. Neste caso, levamos primeiro o disco mais leve ao pino temporario (pino 2), logo levamos o disco mais pesado ao destino e finalmente levamos o disco menor do temporario ao destino. Se podemos levar os dois disco ao destino, também poderiamos levar os dois discos ao pino temporario (seguindo a seguinte sequência: disco menor ao destino, disco maior ao temporario, disco menor ao temporario). Agora imagina que temos 3 discos no origem. O que podemos fazer é levar os dois discos menores ao temporario (isso ja sabemos fazer), logo levar o disco mais pesado ao pino destino e finalmente os dois discos menores levar para o pino destino usando o pino origem.
O que podemos fazer é levar os dois discos menores ao temporario (isso ja sabemos fazer), logo levar o disco mais pesado ao pino destino e finalmente os dois discos menores levar para o pino destino usando o pino origem. Em forma geral se temos, N discos, levamos os N-1 discos menores ao pino temporario, o disco maior levamos ao destino e depois levamos os N-1 discos ao destinos. Portanto o algoritmo seria:
procedimento Hanoi(N, Orig, Dest, Temp, contador) se N = 1 então mover o menor disco do pino Orig para o pino Dest; acrecentar o contador; senão Hanoi(N-1, Orig, Temp, Dest, contador); mover o N-ésimo menor disco do pino Orig para o pino Dest; acrecentar o contador; Hanoi(N-1, Temp, Dest, Orig, contador); fim-se fim
Em cada movemento vamos acrecentar o valor de um contador para determinar o numero de movimentos. Para que o contador possa ser alterado quando retornar a função, valor utilizar a ideia de passagem de parametro por referencia, o que foi aprendido na aula anterior. Vejamos como seria o programa:
Program testahanoi; Var n,contador:integer; Procedure Hanoi(n,origem,dest, temp:integer; var contador:integer); Begin if(n=1) then begin contador:=contador+1; end else begin Hanoi(n-1, origem, temp, dest,contador); contador:=contador+1; Hanoi(n-1, temp, dest, origem,contador); end; End; Begin writeln('entre com o numero de discos'); readln(n); contador:=0; Hanoi(n,1,2,3,contador); writeln('o numero de movimentos eh: ',contador); End.
Faça um programa principal para testar o problema das torres da Hannoi
Faça um programa principal para testar o problema das torres da Hannoi Faça os exercícios de recursão da Lista Complementar 4