Funções Recursivas
Alguns slides retirados de:
ROSA, J. L. G. SCC120 - Capítulo 8 Funções
Recursivas em C. http://www.icmc.usp.br/~joaoluis. 2010.
LARA, S. M. A. de. Recursão em C. Universidade de São Paulo – São Carlos – Instituto de Ciências
Funções Recursivas
•
A recursão é uma técnica que define
um problema em termos de uma ou
mais versões menores deste mesmo
problema
•
Esta ferramenta pode ser utilizada
sempre que for possível expressar a
solução de um problema em função do
próprio problema
3
Funções Recursivas
Funções e procedimentos recursivos são
aqueles que apresentam como
característica poder chamar a si próprios.
A cada nova chamada da função ou
sub-rotina as anteriores ficam suspensas até
esta última ser resolvida.
Quando a última for resolvida haverá um
retorno sucessivo das chamadas,
resolvendo-as uma a uma.
Funções Recursivas
• Trazendo a recursividade para o nosso cotidiano um ótimo exemplo está na ação de contar um saco de moedas, onde a cada ato de retirar uma moeda do saco precisa-se “contar dinheiro” que corresponde a identificar qual é o valor da moeda e somá-la à quantia que ainda está no saco.
• Para identificar a quantia que ainda está no saco basta chamar a mesma função “contar dinheiro” novamente, porém dessa vez já considerando que essa moeda não está mais lá.
• E este processo de retirar uma moeda, identificar seu valor e somar com o restante do saco se repete até que o saco esteja vazio, quando atingiremos o ponto de parada e a função
retornará o valor zero, indicando que não há mais moedas no saco.
Funções Recursivas
•
Nesse ponto a função “contar dinheiro” foi
chamada um número de vezes igual a
quantidade de moedas no saco, e a última
chamada começa a devolver os valores de
retorno de cada instância da função, iniciando
por zero (saco vazio), somado ao valor da
última moeda, da penúltima, etc, até retornar à
primeira chamada referente a primeira moeda, e
nesse momento a função inicial se encerra
trazendo como valor de retorno a soma dos
valores de todas as moedas que estavam no
saco.
6
Funções Recursivas
O conceito de recursão pode
simplificar a elaboração de soluções
para determinados tipos de problema.
Mas, por questões de limitações de
espaço de memória, ou tempo, as
soluções não recursivas sejam
Funções e Sub-rotinas
Recursivas
•
Quando a recursão acontece, várias ações
ocorrem:
•
A função começa a execução do seu primeiro
comando cada vez que é chamada;
•
Novas e distintas cópias dos parâmetros
passados por valor e variáveis locais são
criadas;
•
A posição que chama a função é colocada
em estado de espera, enquanto que o nível
gerado recursivamente esteja executando.
Funções e Sub-rotinas
Recursivas
•
Cada vez que uma função é chamada de
forma recursiva, é guardada uma cópia
dos seus parâmetros de forma a não
perder os valores dos parâmetros das
chamadas anteriores.
•
Em cada instância da função, só são
diretamente acessíveis os parâmetros
criados para esta instância, não sendo
acessíveis os parâmetros de outras
instâncias.
9
Funções e Sub-rotinas
Recursivas
Todo cuidado é pouco ao se fazer funções
recursivas.
A primeira coisa a se providenciar é um
critério de parada.
Este vai determinar quando a função deverá
parar de chamar a si mesma, impedindo
uma recursividade sem fim.
Um ponto importante a ser considerado é
que cada vez que a função é chamada
recursivamente, ela deve estar mais
próxima de satisfazer a condição básica,
que é a condição de interrupção da
Funções Recursivas –
Exemplo com a main
/*ProgC095.cpp - Primeira Recursão*/ #include <iostream>
using namespace std; int main (){
int a, b, c, opcao;
cout <<"Digite o valor de A: "; cin >> a; cout <<"Digite o valor de B: "; cin >> b; c=a+b;
cout <<"O resultado de A + B e "<<c<<"\n\n";
cout << "Deseja reiniciar o programa e realizar outro calculo?\n1. Sim\t2.Nao\n\n=> "; cin >> opcao; if (opcao==1) main(); else return 0; } Condição de parada
Chamada da função main(), repete todo o programa
Funções Recursivas
•
Há certos algoritmos que são mais eficientes
quando feitos de maneira recursiva, mas a
recursividade quando usada incorretamente,
tende a consumir muita memória e ser
lenta.
•
A memória é consumida cada vez que o
computador faz uma chamada a uma
função.
•
Com funções recursivas a memória do
computador pode se esgotar rapidamente.
Funções Recursivas -
Exemplo
//ProgC096.cpp - SOMATORIO Recursivo #include <iostream> int somatorio(int x) { if( x == 1 ) return 1; else return(x + somatorio(x -1)); } int main() { int num;
std::cout << "Entre com um numero: "; std::cin >> num;
std::cout << "O somatorio de 0 ate " << num << " e: " << somatorio(num) << "\n"; return 0; } Função Recursiva Condição de parada Chamada Recursiva Chamada Inicial
Funções Recursivas -
Exemplo
Funções Recursivas - Exemplo
/*ProgC097.cpp - Escrever uma sequência de números*/
#include <iostream> using namespace std;
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;
cout << "Introduza o numero inicial (>0)"; cin >> numero; cout << endl; esc_numero1(numero); cout << endl; esc_numero2(numero); cout << endl; return 0;} Função Recursiva Função Recursiva Condição de parada Condição de parada Chamada Recursiva Chamada Recursiva Chamada Inicial Chamada Inicial
Funções Recursivas - Exemplo
03/08/13
esc_numero1(4) esc_numero1(3) esc_numero1(2) esc_numero1(1)esc_numero1(0) Para as chamadas Escreve 1 na tela Escreve 2 na tela Escreve 3 na tela
Escreve 4 na tela esc_numero2 (4)
Escreve 4 na tela esc_numero2 (3) Escreve 3 na tela esc_numero2 (2) Escreve 2 na tela esc_numero2 (1) Escreve 1 na tela esc_numero2 (0) Finaliza todas as chamadas
16
Funções e Sub-rotinas
Recursivas - Exemplo
/*ProgC098 - Fatorial recursivo.*/ #include <iostream> #include <cstdlib> using namespace std; long fatorial(int n); int main () { int n, cont;
for(cont = 1; cont <= 10; cont++) { cout << "\nDigite um numero: "; cin >> n;
cout << "O fatorial de " << n << " e: " << fatorial(n) << endl; }
system("PAUSE"); return 0;
}
long fatorial (int n) { if (n<=0)
return 1; else
return (long(n) * fatorial(n-1)); }
Protótipo da função para calcular o fatorial de um número. Chamada externa da função Teste de parada da recursividade Chamada interna da função
Funções Recursivas - Exemplo
03/08/13
fatorial (5) 5 * fatorial (4) 4 * fatorial (3) 3 * fatorial (2) 2 * fatorial (1) 1 * fatorial (0) 1 * 1 2 * 1 3 * 2 4 * 6 5 * 24 120Funções Recursivas -
Exemplo
/*ProgC099.cpp - FIBONACCI Recursivo*/ #include <iostream>
using namespace std; int fibonacci(int N) { if( N == 1 ) return 1;
else if(N == 2) return 1;
else return(fibonacci(N-1) + fibonacci(N-2)); } int main() {
int num, F;
cout << "Entre com um numero: "; cin >> num;
cout << "A serie de Fibonacci para " << num << " elementos e:\n"; for(F=1;F <= num;F++) { cout << fibonacci(F) << " ";} cout << "\n\nOk\n\n"; return 0;}
03/08/13
Teste de parada da recursividade Função Recursiva Chamadas internas Chamada externaFunções Recursivas -
Exemplo
03/08/13
Fibonacci(5)
Fibonacci(4) + Fibonacci(3)
Fibonacci(3) + Fibonacci(2) Fibonacci(2) + Fibonacci(1)
Fibonacci(2) + Fibonacci(1)
5
3 + 2
2 + 1 1 + 1
/*ProgC100.cpp - CONTA DIGITOS*/ #include <iostream> #include <cmath> using namespace std; int digitos(int x) { if(abs(x) < 10 ) return 1; else return(1 + digitos(x/10)); } int main() { int num;
cout << "Entre com um numero: "; cin >> num;
cout << "\nO numero de dígitos de " << num << " e: " << digitos(num) << "\n"; return 0; }
03/08/13
Funções Recursivas -
Exemplo
Função Recursiva Chamada externa Chamada recursivaFunções Recursivas - Exemplo
03/08/13
digitos (1452) 1 + digitos (145) 1 + digitos (14) 1 + digitos (1) 1 + 1 1 + 2 1 + 3 4/*ProgC101.cpp - Cálculo do resto da divisão de dois números*/ #include <iostream>
using namespace std;
int res(int x, int y) { if (x < y)
return(x);
return (res(x - y, y)); }
int main () { int a, b;
cout << "Digite dois números: "; cin >> a >> b;
cout<<"\nO resto da divisão entre "<<a<<" e "<<b<<" e:"<<res(a,b);
return 0; }
03/08/13
Funções Recursivas - Exemplo
Função Recursiva
Chamada externa Chamada recursiva