Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Apostila de C
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
5
Issues
5
List
Boards
Labels
Service Desk
Milestones
Merge Requests
1
Merge Requests
1
Operations
Operations
Incidents
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
PET Computação
Apostila de C
Commits
5f8ec801
Commit
5f8ec801
authored
Apr 24, 2015
by
João Denis Rodrigues
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of gitlab.c3sl.ufpr.br:pet/apostila_c
parents
6ac003c4
1bdd7022
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
66 additions
and
182 deletions
+66
-182
recursividade.tex
recursividade.tex
+66
-182
No files found.
recursividade.tex
View file @
5f8ec801
...
...
@@ -2,232 +2,116 @@
\begin{document}
Recursividade
Recursividade é uma t'ecnica de programação que envolve utilizar defini,cões recursivas de modo a simplificar vários algoritmos.
\chapter
{
RECURSIVIDADE
}
Uma definição recursiva é uma defini,c~ao que utiliza a si mesmo para se definir. A princípio, a id'eia
\emph
{
Recursividade
}
é uma técnica de programação que envolve utilizar definições recursivas de modo a simplificar vários algoritmos.
Uma definição recursiva é uma definição que utiliza a si mesma para se definir. A princípio, a ideia
pode parecer confusa e obscura, mas na realidade é um conceito relativamente simples.
Por exemplo, é possível definir uma exponenciação dessa maneira:
Seja n, k 2 N,
n
0
= 1
n
k
= n:n
k
\Gamma
1
Observe que, no exemplo acima, a exponenciação nk está sendo definida através de uma outra exponencia,c~ao (n
k
\Gamma
1
), ou seja, este é um caso em que a exponenciação 'e definida atrav'es dela mesma (o que
é uma definição recursiva ou tamb'em chamada de recorr
^
encia).
Analisando um pouco melhor o exemplo acima, n
k
\Gamma
1
também 'e uma exponenciação, portanto poderia
utilizar a mesma definição para se definir, ou seja, se tomamos n
k
\Gamma
1
= n:n
k
\Gamma
2
ê assim podemos definir
n
k
\Gamma
2
, nk
\Gamma
3, etc.
Note que deveria haver um momento em que a definição termina, pois sen~ao seria impossível calcular
n
k
. Por isso, toda definição recursiva deve ser acompanhada de um caso trivial que será o final da
definição. No exemplo apresentado, n
0
= 1 é o caso trivial e determina o final da recursividade sobre n
k
.
Assim, seria possível calcular, por exemplo 3
3
:
Seja n, k
\in
N,
3
n
^
0 = 1
3
n
^
k = n.n
^{
k-1
}
= 3:3
2
Observe que, no exemplo acima, a exponenciação n
^
k está sendo definida através de
uma outra exponenciação (n
^{
k-1
}
), ou seja, este é um caso em que a exponenciação
é definida através dela mesma (o que é uma definição recursiva ou também chamada de recorrência).
, 3
Analisando um pouco melhor o exemplo acima, n
^{
k-1
}
também é uma exponenciação,
portanto poderia utilizar a mesma definição para se definir, ou seja, se tomamos
n
^{
k-1
}
= n.n
^{
k-2
}
e assim podemos definir, n
^{
k-3
}
, etc.
2
Note que deveria haver um momento em que a definição termina, pois senão seria
impossível calcular n
^
k. Por isso, toda definição recursiva deve ser acompanhada
de um caso trivial que será o final da definição. No exemplo apresentado, n
^
0 = 1
é o caso trivial e determina o final da recursividade sobre n
^
k.
= 3:3
Assim, seria possível calcular, por exemplo 3
^
3:
1
3
^
3 = 3.3
^
2, 3
^
2 = 3.3
^
1, 3
^
1=3.3
^
0, 3
^
0 = 1
\Rightarrow
3
^
1 = 3.1, 3
^
2 = 3.3, 3
^
3 = 3.3.3
, 3
1
= 3:3
0
, 3
0
= 1 ) 3
1
= 3 3
2
= 3:3 e 3
3
= 3:3:3
Na linguagem C, funções podem chamar a si próprias, ou seja, fun,c~oes podem ser recursivas também,
Na linguagem C, funções podem chamar a si próprias, ou seja, funções podem ser recursivas também,
já que podem ser definidas através delas mesmas.
Para uma linguagem permitir recursividade, uma função deve estar apta a chamar a si própria. Um
êxemplo clássico de recursividade em programação é a fun
,c~a
o que calcula o fatorial de um número.
êxemplo clássico de recursividade em programação é a fun
çã
o que calcula o fatorial de um número.
\begin{lstlisting}
-Exemplo 1: Duas versões de fatorial -
/* não recursiva */
/* não recursiva */
int fat (int n)
f int t, resp;
{
int t, resp;
resp = 1;
for (t = 1; t <= n; t++)
resp = resp*t;
return resp;
}
resp = 1;
for (t=1; t!=n; t++)
resp = resp*t;
return resp;
g
/* recursiva */
int fat (int n)
f int resp;
if (n!2) return 1;
resp = fat(n-1)*n;
return resp;
g
85
86 AP
^
êNDICE E. RECURSIVIDADE
O funcionamento da função fat n~ao recursiva deve estar claro. Ela usa uma repeti,c~ao come,cando
{
int resp;
if (n < 2) return 1;
resp = fat(n-1)*n;
return resp;
}
\end{lstlisting}
O funcionamento da função
\emph
{
fat
}
não recursiva deve estar claro. Ela usa uma repetição começando
com 1 e terminando com o valor objetivado e multiplica progressivamente cada número pelo produto
acumulado.
A operação da fun,c~ao fat recursiva é um pouco mais complexa. Quando a fun,c~ao fat 'e chamada
com um argumento 1, a função retorna 1 (esse é o caso trivial da defini,c~ao recursiva do fatorial), caso
contrário, ela retorna o produto de fat(n-1)*n.
Para avaliar essa expressão, fat é chamada com n-1. Isso acontece at'e que n seja igual a 1, quando as
chamadas `a função come,cam a retornar. O exemplo abaixo ilustra a configura,c~ao da pilha na memória
durante cada passo da sequ
^
encia de execução da fun,c~ao fat(4).
)
resp/n
)
resp/n
resp/n
A operação da função fat recursiva é um pouco mais complexa. Quando a função
\emph
{
fat
}
é chamada
com um argumento 1, a função retorna 1 (esse é o caso trivial da definição recursiva do fatorial), caso
contrário, ela retorna o produto de
\emph
{
fat(n-1)*n
}
.
)
Para avaliar essa expressão, fat é chamada com n-1. Isso acontece até que n seja igual a 1, quando as
chamadas à função começam a retornar. O exemplo abaixo ilustra a configuração da pilha na memória
durante cada passo da sequ
^
encia de execução da função
\emph
{
fat(4)
}
.
resp/n
resp/n
resp/n
% FIXME: Inserir a imagem
)
resp/n
resp/n
)
resp/n
)
Figura E.1: Estágios da pilha na chamada recursiva de fat(4)
Quando uma função chama a si própria, as novas variáveis locais e os par
^
ametros s~ao alocados na
pilha (que é uma região da memória) e o c'odigo da funç~ao 'e executado com esses novos valores a partir do
início. Uma chamada recursiva não faz uma nova cópia da funç~ao. Somente os argumentos e as variáveis
Quando uma função chama a si própria, as novas variáveis locais e os parâmetros são alocados na
pilha (que é uma região da memória) e o código da função é executado com esses novos valores a partir do
início. Uma chamada recursiva não faz uma nova cópia da função. Somente os argumentos e as variáveis
são novas.
Quando cada chamada recursiva retorna, as antigas variáveis locais e os par
^
a
metros são removidos da
pilha e a execução recome
,ca no ponto de chamada da fun,c~ao dentro da fun,c~a
o.
Quando cada chamada recursiva retorna, as antigas variáveis locais e os par
â
metros são removidos da
pilha e a execução recome
ça no ponto de chamada da função dentro da funçã
o.
A principal vantagem das funções recursivas é que elas podem ser usadas para criar vers
~o
es mais claras
A principal vantagem das funções recursivas é que elas podem ser usadas para criar vers
õ
es mais claras
ê mais simples de muitos algoritmos complexos do que os seus equivalentes iterativos.
Por exemplo, o algoritmo de ordenação rápida é bastante difícil de ser implementado pelo modo
iterativo. Também, alguns problemas, especialmente os relacionados com IA (intelig
^
e
ncia artificial),
levam a si próprios a soluções recursivas. Finalmente, muitas defini
,c~o
es são naturalmente recursivas, o
que torna muito mais fácil implement
'a
-las utilizando recursividade.
iterativo. Também, alguns problemas, especialmente os relacionados com IA (intelig
ê
ncia artificial),
levam a si próprios a soluções recursivas. Finalmente, muitas defini
çõ
es são naturalmente recursivas, o
que torna muito mais fácil implement
á
-las utilizando recursividade.
Na criação de fun
,c
ões recursivas é muito importante que seja definido um caso trivial que determina
quando a função deverá come
,car a retornar valores. Se n~ao houver um caso que obrigue a fun,c~a
o a parar
de chamar a si mesma, o programa certamente irá entrar estourar a pilha, j
'a
que a memória não é infinita.
Na criação de fun
ç
ões recursivas é muito importante que seja definido um caso trivial que determina
quando a função deverá come
çar a retornar valores. Se não houver um caso que obrigue a funçã
o a parar
de chamar a si mesma, o programa certamente irá entrar estourar a pilha, j
á
que a memória não é infinita.
ê.1 Exercícios
\section
{
Exercícios
}
1. Crie uma definição recursiva para as seguintes opera
,c
ões:
1. Crie uma definição recursiva para as seguintes opera
ç
ões:
a) soma de dois números a e b;
b) multiplicação de dois números a e b ;
c) cálculo do n-ésimo número de uma PA de razão r;
d) cálculo do n-ésimo número de uma PG de razão q;
2. Implemente a função soma pa (int x, int r, int n) que retorna a soma dos n termos de uma PA de
2. Implemente a função soma
_
pa (int x, int r, int n) que retorna a soma dos n termos de uma PA de
termo inicial x e razão r.
3. Desenhe um diagrama da memória para a seguinte chamada de soma pa:
soma pa(1,3,4);
\end{document}
3. Desenhe um diagrama da memória para a seguinte chamada de soma
_
pa:
\begin{verbatim}
soma pa(1,3,4):
\end{verbatim}
\end{document}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment