Você está na página 1de 8





1. Funes Recursivas
Qualquer funo em linguagem C/C++ pode ser chamada de um modo recursivo, isto , uma
funo pode chamar-se a si prpria. O nmero de vezes que uma funo pode ser chamada
recursivamente limitado ao tamanho da pilha (stack), se este valor for alcanado, o
programa termina com error: Stack Fault ou Stack Overflow.

Definio:
Funo Recursiva uma funo que invoca a si prpria, ou invoca outra funo, e na
sequncia das diversas subfunes, uma das subfunes invoca a primeira funo.

Cada vez que uma funo chamada de forma recursiva, alojado e guardado uma cpia
dos seus parmetros por forma a no perder os valores dos parmetros das chamadas
anteriores. Em cada instncia da funo, s so directamente acessveis os par

etros

criados para esta instncia, no sendo directamente acessveis os parmetros de outras


instncias.

A informao guardada na invocao de uma funo designada por Estrutura de


Invocao e consiste basicamente na seguinte informao:

Endereo de retorno (quando a funo terminar o programa deve continuar a sua

execuo na linha seguinte invocao da funo)


Estado dos registos e flags do CPU

Variveis passadas como argumentos para a funo (por valor, referncia, etc.)
Varivel de retorno (por valor, referncia, etc.)

A invocao de uma funo recursiva igual invocao de uma funo no recursiva, na


qual necessrio guardar uma estrutura de invocao, sendo esta estrutura libertada depois
do fim da execuo da funo e afectao/actualizao do valor de retorno.

 
  
!"#$%

&' (
*)+,)

./012
3 4 5 4676/

Caractersticas das funes recursivas:


As funes recursivas contm duas partes fundamentais:
1. Ponto de Paragem: o ponto de paragem da recursividade resolvido sem utilizao
de recursividade, sendo este ponto geralmente um limite superior ou inferior da regra
geral.
2. Regra Geral: o mtodo geral da recursividade reduz a resoluo do problem
atravs da invocao recursiva de casos mais pequenos, sendo estes casos mais
pequenos resolvidos atravs da resoluo de casos ainda mais p equenos, e ass
sucessivamente, at atingir o ponto de paragem que finaliza o mtodo.

Exemplo:

(n == 0) 1
Factorial (n) =
(n) n * (n 1)!

Ponto de Paragem
Regra Geral

Nota:
As variveis declaradas como estticas, no requerem novo armazenamento, em cada
invocao da funo recursiva. Estas variveis existem durante todo o programa, no sendo
criado cpias destas variveis na invocao de uma funo de modo recursivo.

Desenho de algoritmos recursivos:


1.

Obter uma soluo de como o problema pode ser dividido em passos menores

2.

Definir um ponto de parage

3.

Definir uma regra geral

4.

Verificar se o algoritmo termina

5.

Desenhar uma rvore de execuo do programa, mostrando o desenvolvimento do


processo.

Utilizar recursividade ou no ?

Na fase de concepo, os mtodos recursivos so um bom processo flexvel de


pensamento

Na fase de imp ementao, necessrio avaliar os diversos mtodos e questionar


qual o melhor mtodo para as circunstncias especificas (mais eficaz e eficiente).

849:1
7:/936/; 2
<:27="7>?<@

;A:'4(9
7CBD6/EB

FGHIJ
K L M LNONG

Concluso:
A recursividade deve ser utilizada quando a forma recursiva a forma mais simples e
intuitiva de implementar uma soluo para a resoluo do problema.

Exemplo n. 1
Escrever uma sequncia de nmeros na vertical
#include <iostream.h>
void esc_numero1(int num)
{
if (num > 0)
{ esc_numero1(num-1);
cout << num << " ";
}
}
void esc_numero2(int num)
{
if (num > 0)
{ cout << num << " ";
esc_numero2(num-1);
}
}
int main()
{
int numero=0;
cout << "Introduza o numero inicial (>0)";
cin >> numero;
esc_numero1(numero);
cout << endl;
esc_numero2(numero);
}

PLQRI
ORGQKNGS J
TRJOU"OVWTX

SYR'L(Q
OCZDNGEZ

[\]^_
` a b acdc\

Exemplo n. 2
Funo Factorial
Mtodo Recursivo
long int factorial1( int num )
{
if (num < 0)
{ // Se o nmero menor que zero ento retornar erro.
retun(-1);
}
if ( (num == 0) || (num == 1) )
{ // Se o numero igual a 0 ou 1, ento o seu factorial 1.
return(1);
}
else
{ // Caso contrrio, invocar recursivamente a funo.
return( num * factorial1( num - 1 ) );
}
}

Mtodo Iterativo
long int factorial2( int num )
{ long int resultado = 1;
if (num < 0)
{ // Se o nmero menor que zero ento retornar erro.
retun(-1);
}
for(int i = 2; i <= num; i++)
{ resultado *= i; }
return(resultado);
}
void main()
{
int numero=0;
long int fact=0;
cin >> numero;
fact = factorial1(numero);
cout << endl << numero << != << fact << endl;
fact = factorial2(numero);
cout << endl << numero << != << fact << endl;
}

Nota:
A funo factorial retorna o mesmo valor em ambas as implementaes, contudo, a forma
sem recursividade ligeiramente mais eficiente.

eafg^
dg\f`c\h _
ig_dj"dklim

hng'a(f
dpoqc\ro

stuvw
x y z y{|{t

Exemplo n. 3
Inverso de uma string
Mtodo Recursivo
void stringinv_aux (char * s, int i, int j)
{
if ( j - i > 2)
{ stringinv_aux (s, i + 1, j 1); // Inverter a sub-string.
}
// Trocar os caracteres extreinos.
char aux = s[j]; s[j] = s[i]; s[i] = aux;
}
void stringinv(char * str)
{
stringinv_aux(str, 0, strlen(str));
}
exemplo: Inverter a string bonitos
instncia
i
j
string entrada da funo string sada da funo
1
0
6
bonitos
sonit
2
1
5
sonit
sonit
3
2
4
sonit
sotinob

Mtodo Iterativo
void stringinv_aux(char * str, int i, int j)
{
for( int i = O ; i < j ; ++i, --j )
{ // Trocar os caracteres extremos.
char aux = s[j]; s[j] = s[i]; s[i] = aux;
}
}
void stringinv(char * str)
{
stringinv_aux(str, 0, strlen(str));
}

}y~v
|t~x{t w
w|"|

'y(~
|CD{tE




Exemplo n. 4
Converter nmeros inteiros em strings
Mtodo Recursivo
void itoa_aux(int num, char * &s)
{
if ( num == 0 ) return ;
itoa_aux( int(num / 10), s);
*s++ = n % 10 + '0';
}
void itoa(int num, char *s)
{
if (num < 0) // Se o valor for negativo.
{ *s++ = -;
n = -n;
}
itoa_aux( num , s );
*s = 0;
// Terminar a String
)

Mtodo Iterativo
void itoa(int num, char * s)
{ int valor, i = 0, j;
char c;
if ( (valur = num) < 0)
{ num = -num;
}
do
{ s[i++]= n %10 + 0;
}
while(( num /= 10) > O );
if ( valor < 0)
{ s[i++] = -; }
s[i] = \0;
// Inverter a string
for ( j = 0, --i; i > j ; --i, ++j)
{ c = s[i]; s[i] =s[j]; s[j] = c; }
}



"

'(
,C




Exemplo n. 5
Clculo do resto da diviso de dois nmeros
Considere a seguinte funo que calcula o resto da diviso de dois nmeros, atravs da
sucessiva subtraco ao 1 nmero do valor do 2 nmero.

Mtodo Recursivo
#include <iostream>
int res(int numerador, int denominador);
int res(int x, int y)
{
if (x < y) return(x);
return( res(x y, y) );
}

Mtodo Iterativo
#include <iostream>
int res(int numerador, int denominador);
int res(int x, int y)
{
while(x >= y)
{ x = x y;
}
return( x );
}



"

'(
,C




Exemplo n. 6
Clculo do resto da diviso de dois nmeros
Considere a seguinte funo que calcula a multiplicao de dois nmeros positivos, maiores qu
zero, atravs de sucessivas somas do primeiro nmero.

Mtodo Recursivo
#include <iostream>
long int mult(int x, int y);
long int mult(int x, int y)
{
if (y == 1)
return(x);
else
return(x + mult(x, y-1));
}

Mtodo Iterativo
#include <iostream>
long int mult(int x, int y);
long int mult(int x, int y)
{ long int res=0;
while( y != 1)
{ res += x;
y--;
}
return(res);
}

Exemplo n. 7
Clculo da seguinte formula:

n
i =1

(i * i )

Mtodo Recursivo
#include <iostream>
long int sumatorio(int num);
long int sumatorio (int num)
{
if (num == 0)
return(0L);
else
return( num * num + sumatorio( num 1 );
}



"

'(
CDE

Você também pode gostar