Estrutura de Dados, Pilha, Fila, Recursividade PDF
Estrutura de Dados, Pilha, Fila, Recursividade PDF
Estrutura de Dados, Pilha, Fila, Recursividade PDF
',J
,I!
,'"
I!I "
Pilha
41
I
""
~'.i
stackpop - retoma o elemento superior da pilha sem remov-lo (equivalente s operaes de pop e um push).
Pilha
A aplicao da estrutura de pilhas mais freqente em compiladores e sistemas operacionais, que a utilizam para controle de dados, alocao de variveis
na memria etc.
problema no uso de pilhas controlar o final da pilha, Isto pode ser feito
de vrias formas, sendo a mais indicada criar um mtodo para verificar se existem
mais dados na pilha para serem retirados.
Uma pilha um conjunto ordenado de itens, no qual novos itens podem ser
inseridos e a partir do qual podem ser eliminados itens de uma extremidade, chamada topo da pilha. Tambm chamada de lista linear, onde todas as inseres e
eliminaes so feitas em apenas uma das extremidades, chamada topo. A figura
3.1 mostra a representao de uma pilha.
Pilha
Dado 05
Dado 04
Dado 03
Dado 02
Dado 01
Figura 3.1: Exemplo de Pilha
!'
:,11
1,;1
:,1!
<)
Pilha 43
Topo
--1 F
H
F
n.'__'
_._
_.
._
._.
~ __
... __
o
c
2
3
6
7
Antes de programar a soluo de um problema que usa uma pilha, necessrio determinar como representar uma pilha usando as estruturas de dados
existentes na linguagem de programao. Uma pilha um conjunto ordenado de
itens, e a linguagem C j contm um tipo de dado que representa um conjunto
ordenado de itens: o vetor. Ento, sempre que for necessrio utilizar a estrutura
---------
~~
j!
3.2 Pilhas em C
"
Pilha
44
Algoritmo
33
retum pilha[posl;
}
38
*/
43 I push(2)j
push(3)j
printf("\nTamanho
13 I
da pilha
48 I printf("\npegando
dado
dado
dado
printf("\npegando
printf(" \nPegando
I #include -cstdio.h
int pilha[20]j
int pos-O,
")j
pushf I);
53
printf("\nTamanho
I retum o,
%d", sizeO)j
da pilha:
da pilha:
da pilha:
da pilha
%d", pop),
%d", popO)j
%d", pop),
%d", sizeO)j
Uma pilha em C podeser declarada como uma estrutura contendo dois objetos: um vetor para armazenar os elementos da pilha e um inteiro para indicar a
posio atual do topo da pilha (programa 3.2).
Programa
pilha[pos]=valorj
/" Empilha um novo elemento. No verifoada a capacidade
mxima da pilha. */
pos++j
rerurn;
*/
#include -cstdio.h
#include -cstdlib.h>
#define TAMANHO_PILHA 100
int popt)
/" Retoma o elemento do topo dafilha. No uerificado
ofinal da pilha. */
retum (pilhaj=posl),
/* plograma-pilha_02.c
23 I (
int topo,
int itens[TAMANHO_PILHA]j
10 I
}j
i~.
45
28
int sizet)
retum pOSj1* retoma o topo da pilha */
}
if( p-c-topo == -1
Pilha
65
47
pushtcx.Z);
push(&x,3)j
return L;
}
20 I
printf(" \nTamanho
printf("\nElemento
return Oj
da pilha
do topo
%d", size(&xj
da fila %d",stackp0p(&xj
70
75
printf("\n%d",
printf("\n%d",
printf("\n%d",
printf("\n%d",
return O;
}
pop(&xj
pop(&xj
pop(&xj
pop(&xj
3.3 Exerccios
void push(struct pilha "p, int e)
35 I {
- 1
printf("\nEstouro
da pi Lha ");
exitf l);
}
I" aps oerificar se no baueria estouro na capacidade da pilha,
criada U11to noua posio na pilha e o elemento armazenado */
40
p-c-itensj=-Ip-c-topoj]
: e;
1. Dada uma pilha P, construir uma funo que inverte a ordem dos elementos dessa pilha, utilizando apenas uma estrutura auxiliar. Definir
adequadamente a estrutura auxiliar e prever a possibilidade da pilha
estar vazia.
2. Construir uma funo que troca de lugar o elemento que est no topo
da pilha com o que est na base da pilha. Usar apenas uma pilha como
auxiliar.
return,
45
50 I
retum p-c-itensjp-stopo],
int main(void)
60 I {
struct pilha x;
x.topo -I,
pushtcx.l);
,c:,. ,-
Fila
49
~I !
1'.1
11
Tomando a fila da figura 4.1 como exemplo, o item a apresenta a fila no seu
estado inicial e executado o conjunto de operaes:
; '!
,i
i
item B)
11 Fila
-,
"-
Incio
a)ln~
b)
____ J~----
Final
Final
Uma fila um conjunto ordenado de itens a partir do qual se podem eliminar itens numa extremidade - incio da fila - e no qual se podem inserir itens na
outra extremidade - final da fila.
Ela uma prima prxima da pilha, pois os itens so inseridos e removidos
de acordo com o princpio de que o primeiro que entra o primeiro que sai - first in,
first out (FIFO).
conceito de fila existe no mundo real, vide exemplos como filas de banco,
pedgios, restaurantes etc. fu operaes bsicas de uma fila so:
<,
"-
"Inicio
-,
Inicio
d)
c)
Final
Final
"-
50
Fila
Algoritmo
Algoritmo
Input: A varivel que contm a fila (Q) e o elemento a ser colocado na fila (x)
Output: Sem retorno
1 begin
2
Q[ fim de Q]<-- x
3
if final de Q = comprimento de Q then
4
fim de Q<-- 1
5
return
6
else
7
Q[ fim de Q]--- fim de Q + 1
8
return
9
endif
10 end
Algoritmo
1
2
3
4
Algoritmo
4.2 Filas em C
A exemplo do que ocorre com estrutura em pilha, antes de programar a
soluo de um problema que usa uma fila, necessrio determinar como representar uma fila usando as estruturas de dados existentes na linguagem de programao. Novamente na linguagem C podemos usar um vetor, Mas a fila
uma estrutura dinmica e pode crescer infinitamente, enquanto que um vetor na
linguagem C tem um tamanho fixo. Contudo, pode-se definir este vetor com um
tamanho suficientemente grande para conter a fila. No programa 4.1 apresentado um exemplo para manipulao de filas.
Programa
Algoritmo
1
2
3
4
5
6
7
51
/: programa fila
l,c */
#include -csrdio.h
3 I #include -cstdlib.h
#define TAMANHO_MAXIMO
100
struct queue
8 I{
int itens[TAMANHO_MAXIMO];
int front,rear;
};
13 I int empty(struct
queue * pq)
.1
52
Fila 53
i
I
I;
/" se o incio da fila for igual aofinal da fila, a fila est vazia
if( pq-sfront
{
"
18I
63 I int main(void)
== pq->rear )
retum 1;
}
retumO;
68 I
"
void enqueue(struct
23
*j
I(
if( pq->rear + 1 >= TAMANHO_MAXIMO)
(
printf(" \nEstouro
da capacidade
exit(l);
28 I
73
da
fila ,,);
}
pq-c-itens] pq->rear++ ] = x;
78
retum;
}
33
38 I int front(struct
queue
83
* pq)
(
/" o primeiro elemento sempre est no incio do vetar
retum pq-sitensj]:
*j
43
int dequeue(struct
(
int x, i;
if( empty(pq) )
48
queue * pq)
printf(" \nFila
vazia
printfi " \nTamanho
da
printf("\nProximo
da
printf("\nTirando
da
printf("\nTirando
da
printf("\nTirando
da
printf("\nProximo
da
printf("\nTirando
da
%d",
fila
fila
fila
fila
fila
fila
fila
printf(" \nFila
%d", empty(&q;
vazia
No programa 4.1, o vetor foi definido para comportar apenas 100 elementos, caso fosse inserido um 101.Qelemento, haveria o estouro da pilha mesmo
aps vrias operaes de dequeue. Para resolver este problema, na operao
dequeue foi implementada uma tcnica de redistribuio dos elementos na fila,
de tal forma que nunca se chegue a estourar a fila caso haja vrias operaes de
insero ou remoo (exceto se realmente houver 100 elementos da fila e houve
uma tentativa de insero de um novo elemento). O programa 4.2 o trecho que
implementa a tcnica comentada:
Programa 4.2: Reajuste da fila
")j
:}
/" Salva o primeiro elemento e rejaz o arranjo dos itens, puxando o segundo elemento
para oprimeiro, o terceiro para o segundo e assim sucessivamente . j
x = pq->itens[O];
for( i=O; i < pq->rearj i++)
vazia
empty(&q;
%d", size(&q;
%d", front(&q;
%d", dequeuercqj):
%d", dequeuercqj):
%d", dequeuefrqj);
%d", front(&q;
%d", dequeuetcqj);
printf(" \n ,,);
(
printf(" \nFila
exit(l);
53
struct queue q;
q.front = O; q.rear = O;
enqueue(&q,l);
enqueue(&q,2);
enqueue(&q,3);
enqueue(&q,4);
x = pq-c-itensj]:
for( i=O; i < pq->rear; i-)
{
pq-c-itensji] = pq-sirensli-I]:
5 I}
pq->rear--;
pq-e-irensji] = pq-c-itensli-I];
58
}
pq->rear--;
retumx;
Esta tcnica ineficiente, pois cada eliminao da fila envolve deslocar cada
elemento restante na fila. Se uma fila contiver 1000 ou 2000 elementos, cada elemento retirado da fila provocar o deslocamento de todos os demais elementos.
A operao de remoo de um item na fila deveria logicamente trabalhar somen-
54
Fila
1)
55
2)
3)
4)
6)
1. Estado inicial
2. enqueue(D) - O item D armazenado ao final da fila
3. enqueue(E) - O item D armazenado ao final da fila
4.
5.
8)
9)
Programa
/" plograma.fila_02.c
#include -cstdio.h
#include -cstdlib.h
#define TAMANHO_MAXIMO
100
struct queue
*I
5 I #defineTAMANHO_MAXIMO
4 I{
};
struct queue qi
I q.front= q.rear=-1
10
struct queue
{
int itens[TAMANHO_MAXIMO]i
I int front.rear;
}i
10
Fila
56
if( pq-sfront
15
==
pq->rear )
return 1;
int x, i;
if( empty(pq) )
return O;
20
printf(" \nFila
exitrl);
70
vazia ,,);
(
25 I
75
pq->rear = O;
}
30
I else
{
pq->rear++;
80
35
40
85
int main(void)
pq-c-itensjpq-c-rear]= x;
return;
90
45
50
'.~.
55
95
100
105
60
struct queue q;
q.front = -1;
q.rear = - 1;
enqueue(&q,l);
enqueue(&q,2);
enqueue(&q,3);
enqueue(&q,4);
printf(" \nTamanho
printf(" \nProximo
printf("\nTirando
printf(" \nTirando
printf(" \nTirando
printf("\nProximo
printf("\nTirando
printf(" \nTamanho
enqueue(&q,5);
enqueue(&q,6);
enqueue(&q,7);
enqueue(&q,8);
da
da
da
da
da
da
da
da
fila
fila
fila
fila
fila
fila
fila
fila
%d", size(&q));
%d", front(&q));
%d", dequeue(&q));
%d", dequeue(&q));
%d", dequeue(&q));
%d", front(&q));
%d", dequee(&q));
%d", size(&q));'
.
.
57
Ij
58
Fila
110 1
115 1
enqueue(&q,9)j
printf("\nTamanho
printf("\nProximo
printf("\nTirando
printf("\nTirando
printf(" \nTirando
printf("\nTirando
printf(" \nproximo
printf("\nTirando
printf(" \nTamanho
enqueuefcq.l
120 1
da
da
da
da
da
da
da
da
da
fila
fila
fila
fila
fila
fila
fila
fila
fila
%d", size(&qj
%d", front(&qj
%d", dequeuetcqj),
%d", dequeuefcqj);
%d", dequeuefcqj),
%d", dequeuecql),
%d", front(&qj
%d", dequeuetcqj):
%d", size(&qj
160 1
printf(" \nTirando
printf("\nTirando
printf(" \nTamanho
printf("\nTirando
printf(" \nTamanho
printf("\nTirando
printf(" \nTamanho
printf("\nFila
da
da
da
da
da
da
da
vazia
fila
fila
fila
fila
fila
fila
fila
59
%d", dequeuecqj),
%d", dequeue/cql),
%d", size(&qj
%d", dequeuefcqj);
%d", size(&qj
%d", dequeue/cqj);
%d", size(&qj
%d", empty(&qj
165
printf("\n")j
return o,
O),
enqueue(&q,II)j
enqueuefeq.l),
enqueuetcq.B),
enqueue/Scq.H);
enqueuecq.lS):
125 1
130 1
1351
140 1
4.3 Exerccios
enqueuefcq.I);
enqueue/cq.l Z),
enqueue(&q,18)j
printf(" \nTamanho
printf(" \nProximo
printf("\nTirando
printf("\nTirando
printf("\nTirando
printf("\nTrando
printf("\nTirando
printf(" \nProximo
printf("\nTirando
printf("\nTirando
printf("\nTirando
printf(" \nTamanho
printf(" \nTirando
printf("\nTamanho
printf(" \nFila
da
da
da
da
da
da
da
da
da
da
da
da
da
da
vazia
fila
fila
fila
fila
fila
fila
fila
fila
fila
fila
fila
fila
fila
fila
%d", size(&qj
%d", front(&qj
%d", dequeuecqj);
%d", dequeuetcqj);
%d", dequeuefcqj);
%d", dequeuefcqj):
%d", dequeuercqj);
%d", front(&qj
%d", dequeuetcqj):
%d", dequeuetcqj):
%d", dequeuetcqj),
%d", size(&qj
%d", dequeuefcqj);
%d", size(&qj
%d", emptytcqj);
enqueuetcq.Z);
enqueuercq.Zl),
enqueueicq.Z),
enqueuefcq.Z);
150 1
j'
i
I-
1\
155
enqueue(&q,24)j
enqueue(&q,25)j
printf("\nTamanho
printf(" \nProximo
printf("\nTirando
printf(" \nProximo
printf("\nTirando
da
da
da
da
da
1. Se um vetor armazenando uma fila no considerado circular, O texto sugere que cada operao dequeue deve deslocar para baixo todo
elemento restante de uma fila. Um mtodo alternativo adiar o deslocamento at que rear seja igual ao ltimo ndice do vetor. Quando
essa situao ocorre e faz-se uma tentativa de inserir um elemento na
fila, a fila inteira desloca da para baixo, de modo que o primeiro elemento da fila fique na posio O do vetor. Quais so as vantagens desse
mtodo sobre um deslocamento em cada operao dequeue? Quais as
desvantagens? Reescreva as rotinas dequeue, queue e size usando esse
mtodo.
2. Faa um programa para controlar uma fila de pilhas.
Recursividade
5.1.
Na linguagem C, as funes podem chamar a si mesmas. A funo recursiva se um comando no corpo da funo a chama. Para uma linguagem de computador ser recursiva, uma funo deve poder chamar a si mesma. Um exemplo
simples a funo fatorial, que calcula o fatorial de um inteiro. O fatorial de um
nmero N o produto de todos os nmeros inteiros entre 1 e N. Por exemplo,
3 fatorial (ou 3!) 1 * 2 *3 = 6. O programa 5.1 apresenta uma verso
iterativa para clculo do fatorial de um nmero.
11 Recursividade
Programa
"E no sabendo que era impossvel, foi l e fez:'
Jean Cocteau
I 1
~:
61
o exemplo
61
f=l;
for (r = 1; t<=n; t++)
f=f*t
return f;
l!=l*O!
2!=2*1!
3! = 3 * 2!
4!=4*3!
Logo o fatorial de um nmero tambm pode ser definido recursivamente (ou
por recorrncia) atravs das seguintes regras (representao matemtica) [15, 1]:
n!
= 1, se n = O
n!=n*(n-1)!,sen>O
O programa 5.2 mostra a verso recursiva do programa fatorial.
62
Recursividade
return 1;
A verso no-recursiva de fatorial deve ser clara. Ela usa um lao que
executado de 1 a n e multiplica progressivamente cada nmero pelo produto
mvel.
A operao de fatorial recursiva um pouco mais complexa. Quando fa chamada com um argumento de 1, a funo devolve 1. Caso contrrio, ela devolve o produto de fatorialr (n-l) *n. Para avaliar essa expresso, fatorialr chamada com n-1. Isso acontece at que n se iguale a 1 e as
chamadas funo comecem a retomar.
torialr
24
120
720
63
T" = Lk=lk=1+2+3+
... +(n-2)+(n-1)+n=
110+0
_
[17]
64
Recursividade
Programa
= 1 componente
2=3
a
00
OElEl
[180m
E1E1m0B
5 = 15
int iTotal = O;
while( n > O )
4 I
EI
13
E!
ElE!
E111J
BI1J
OOB
iTotal += n;
ElBB
El00E!
3=6
n--;
10
}
9
[]
e
0m
Dom
GElO
El8ElEl
08080
E1BElIIlO
OOElIJGO
OIJOODElEl
00
I return iTotaI;
}
E!OSB
000El00
6 = 21
7 = 28
'2. Soma-se a prxima coluna com n-1 elementos at que reste apenas 1
elemento.
Supondo que se esteja buscando o quinto elemento (dado pelo nmero 15),
como descobrir este elemento? Basta distribuir entre aslinhas e colunas conforme a figura 5.2 (5+4+3+2+1 = 15).
1--1
IlWlli,
I L::!j I
I I: "
I I: "
lu.ttIl ~
Ir;;wll~
I~I
II!1I r--I
I
11
I@JII~
1111:11l/Ij: 11--1
II~ ... 11128'"
II~.~
~(IIIi!i'/I
.1,; II
1 ..... 1'''' .. 11'" 11--'
:I
"
If@ fm', -,
nas colunas
restantes
____________
5 na primeira
coluna
Total: 15 componentes
1 nesta coluna
o programa
Programa
I :''
fU,J'
I!!J "
11
-1-'------l------~~
I
3 nesta coluna
I~I:~ ~
:
1
I
II
"
II
I
1~11r;;liil11'iil11'W11
ItmlJlll:!!iJll~ll~
r-I
1I
1I
11
1I I I
'1iil'1IIrom"~'I~',Wiil
IffiJllt:!!!.IlllEJlle2Jllll2j:
T'-(LL.
:~::~ ~ Ij]'"
~n' t , J
-,
1f?111f1F;1]
r-I
int triangulo(int n)
g)
1 linha
65
trianguloint o)
if( n == 1)
66
Recursividade
67
int fibc(int n)
2 I(
return n + triangulo(n-I);
int I,h, x, i;
if( n <= 2)
return I;
1 = O;
Chamando a funo
triangulo com n=S
Primeira chamada
i------------n;5-
,,
,,
,,
,,
-- ---
h=1;
-- -- ----:
~'I
~I
'I~~tl
,:;I
,
,
,
,
h =x + I;
}
return h;
~~~.
:g:
,,
ti'::
,,
I~,
:h:
t,,
u~I
f<.(
:~.::
o n-simo nmero definido como sendo a soma dos dois nmeros anteriores. Logo, fazendo a definio recursiva:
~~!;:
li'..:
I~'~I
'~'
hcl
1''
f~~1
..
__ I)~ I
~~,;1:-:
I
I
il
:J
fib(n)
n se n
fib(n)
= fib(n-2)
<=
+ fib(n-l) se n > 2
A sua determinao recursiva impe o clculo direto do valor para dois elementos de base (a primeira e a segunda gerao). No programa 5.6 mostrada a
verso recursiva para calcular o n-simo termo da seqncia de Fibonacci.
Soma 5
Programa
ROlorna 15
Retorna 15
if( n <= 2)
4 I
return I;
}
/" chama a si prprio 2 vezes.'.'.' */
return fibr(n-I) + fibr(n-2);
9 I}
68
Recursividade
Para calcular fibr (5) necessrio calcular fibr (4) e fibr (3) . Conseqentemente, para calcular fibr (4) preciso calcular fibr (3) e fibr (2) . E assim sucessivamente. Este tipo de processamento inadequado, j que o computador
obrigado a fazer trabalho desnecessrio. No exemplo, usando o programa 5.6, para
calcular fibr (5) foi preciso calcular fibr (4) 1 vez, fibr (3) 2 vezes, fibr (2) 3
vezes e fibr (1) 2 vezes. No programa iterativo (programa 5.5), apenas era necessrio calcular fibc (5) , fibc ( 4 ) , fibc (3) , fibc (2) e fibc (1) 1 vez. A figura 5.5
demonstra como ficaria a chamada do programa 5.6 para clculo do stimo termo.
AIgoritmo
2
3
Input: Me N
Output: MDC calculado
begin
r <-- resto da diviso m por n
while r "" O do
m<--n
Il<--r
return
8
9
<--
endw
n;
end
Programa
1
I #include -estdio.h
int mdc(int m, int n)
int r;
whiIe( m % n != O)
r e rn % n;
m e n;
n e r;
11
retumn;
int main(void)
16 I (
e o segundo nmero de
n;
printf(" 6 O, 36
printf(" 3 6, 24
retum O;
e o procedimento
termina, se
%d\n", mdc(60,36;
%d\n", mdc(36,24;
do segundo passo.
o programa
#include -csrdio.h
int mdc(int m, int n)
5 I(
if( n == O)
69
)
70
Recursividade
return
I /eturn
m;
71
O;
lO
int rnain(void)
(
printf(" 6 O, 36
printff" 3 6, 24
return O;
%d\n", rndc(60,36;
%d\n", rndc(36,24;
#include -cstdio.hs
int rndc(int rn, int n)
{
4 I
if( rn == n)
{
return
m;
}
if( rn-n >= n)
9 I
int rnain(void)
{
printf(" 6 O, 36
printf(" 36 , 24
%d\n", rndc(60,36;
%d\n", rndc(J.6,24;
'11 1~"
111 1'!
,
~
~~.f.
72
Recursividade
73
,-L=,
,,-
o algoritmo
Algoritmo 5.2: Passar n peas de uma torre (A) para outra (C)
begin
Passar n-I peas da torre inicial (A) para a torre livre (B)
Mover a ltima pea, para a torre final (C)
Passar n-I peas da torre B para a torre (C)
end
Para solucionar um hanoi de 64 discos, como diz a lenda, so necessrios 18446744073709551615 movimentos (264 - 1) ou 585 bilhes
de anos (considerando um movimento por segundo).
1
2
3
4
*/
hanoi
count(n)
hanoi
count(n-l)
+ 1 + hanoi
count(n-l)
Neste caso, possvel evitar dupla recursividade (como OCOrrecom Fibonacci) de uma forma simples:
hanoi
count(n)
2 * hanoi_count(n-l)
.\.::":'
"
+ 1
10 I
if( discos == 1)
{
printf(" \ t Mova o disco
}
else
ajuda)~'~'
..,
%d de %c para
~I
11
,,
l:
74
fi::
15 I
hanoi( discos-l,origem,ajuda,destino);
printf("\t
Mova o disco
%d de
hanoi( discos-l,ajuda,destino,origem);
Ii
%c para
%c \n",discos,origem,destino);
return;
Programa
20
1*plograma]ecursividade_curiosidade_Ol.c
"!
(
int total_discos;
printf(" Informe
o numero
scanf(" %d",&total_discos);
hanoi( total_discos,' N.,'B', 'C');
printf(" \ n ,,);
retumO;
25 I
de
discos:
,,);
30I~)
/" p1'Ograma]ecursividadccuriosidade_OI.c
"!
#include -csrdio.hs
#include -cmath.h
doublel;
mainl.,o,O)
{
retum
10
15
I)
putchar(l--+22&&_
+44&&mainl,-43,...),_&&0)
( main(-43,++0,O),
( O=(0+21)/sqrt(3-0*22-0*O),I*k4
&&
(fabs(time(O)-607728)%2 5 51443)/405859.-4. 7 +
acos0l2< 1.57[" # "J))
:10 );
1. Disponvel em http://www.iocc.org/years.honI
75
11
Recursividade
#definel**/X
char*d="xO [ ! 4cM, ! "
"4cK'*!4cJc(!4cHg&!4c$j"
"8f'! &-]ge)!'
1 :d+!)
rAc-! *m*"
":d/!4c(b4eO!lr2e2!/tOe4!-y-c6!"
"+I,c6!)f$b(h*c6!
(d'b(i)d5!
(b*a' '&c"
")c5!'b+'&b'c)c4!&b$c'd*c3!&a.h'd+"
101
"dl! %a/g' e+eO! %b-g (d. dj! &c*h' dld-!
(d%g) "
"d4d+! *1, d7d) ! ,h-d; c' ! .bOc>d%!A 'Dc$! (7) 35E"
"!' i cx.
! 2kE '*! -s@d(! (k (fllg&!)
f. e5' f (! +a+)"
"f%2g* ! ?f5f,
!=f-*e/
! <d6el! geO' f3! 6f) -g5! 4d*b"
"+e6!Of%k)d7!+-A'c7!)z/d-+!'n%aO(d5!%cla+/d4"
15 I
"!2)cge2!9b;el!8b>e/!
7cAd-!5fAe+!7fBe(!"
"8hBd&! : iAd$! [73, QO! 1 bF 7! lb?' _6! 1c, 8b4"
"!2b*a,*d3!2n4f2!${4
f.
'!%y4e5!&f%"
"d-A-d7!4c+b)d9!4c-a
'd
: !/i('
'&d"
"; !+1'a+d<!)1*b(d=!'
ma &d>!&d'"
201
"'O_&c?!$dAc@!$cBc@!$
b
<
A&d$'"
":!$d9_&1++A$!%f3a'
nl
_
$ !&"
"f/c(ol_%!
(f+c)q*c
%!
*
f &d+"
"f$s&!-n,d)n(!Oick)
! 3d"
"/bOh*!H'7a,![7*
i]
5
4
71"
25 I "[=ohr&o*t*q*
'*d
*v
*r
; 02"
"7*-=h.l)tcrsth
&t
:
r
9b"
"] .,b-725-.t--11
#r
[
< t8-"
"752793?
<.-;b
].t--+r
I
#
53~
"7-r[/9-X
.v90
<6/<.v;-52/={
k
goh"
301 "./}q; u vto
hr '.i*$engt$
$
,b"
";$1
=t;v;
6
='it.';7='
":
,b-"
"725
= I o'..d
;b] '-- [/+
551
)0"
'''.d
: -?5
I
)0'.'
v/i]q
"-[;
5 2 =' it
0;5335 1 "v96
<7 I
=0
:
d
=0"
"--li ]q-[;
h.
;
"i)q--[;v
9h
.1
<.'
2. http://www.iocc.org/2000/dhyang.hint
76
Recursividade
77
,!
,nS2={cj
u
c&'
n?4=0:d=
. o-40
n_ [; 54={ cj
UC&
n [; 7 6=i] q [; 6 =vsr
,) \0
n=),BihY_gha
r,w,f
3217];int i,
r<X
p;nO{retum
45 I 768?d[X(143+
X r++
768]:r>2659
? 59:
[(r++-768)%
X 947
xl\(p?6:0):(p = 34
;}sO(for(x= n
O;
50 I ?6:0==32;x= n
O
voidJ** /main X O
=O;w=sprintf (X
X
,"char*d="); for
+143;)if(33-( bed
55 I )(if(b<93)(if
XC!
[w++J=34;for XCi
(P?O:I);i<b;
i++
[w++]=sO;o[
w++
e1se
=p?sO:34;}
60 I
(for(i=92;
i-cb;
++)o[w++J=
32;}
e1se o
[w++
=10;0
w]=O
65
. o'
I i
Jq
i]q
u.i
n
I
b
X
*d
x
(
768]
X
xl\
+
X
(
[
;returnx
r
XX
f=l;f <
f++X
35
o
Euclides: n
Hanoi: discos
o[
,x,
XX
)%
=d
) ?
X)
(p
;}
=p
Xo
*d
1)
o
+
J
X
}
]
[
Sem essa sada no recursiva, nenhuma funo recursiva poder ser computada.
Ou seja, todo programa recursivo deve ter uma condio de parada no recursiva.
A maioria das funes recursivas no minimiza significativamente o tamanho do cdigo ou melhora a utilizao da memria. Alm disso, as verses recursivas da maioria das rotinas podem ser executadas um pouco mais lentamente
que suas equivalentes iterativas devido s repetidas chamadas funo. De fato,
muitas chamadas recursivas a uma funo podem provocar um estouro da pilha.
Como o armazenamento para os parmetros da funo e variveis locais est na
pilha e cada nova chamada cria uma nova cpia dessas variveis, a pilha pode provavelmente escrever sobre outra memria de dados ou de programa. Contudo,
no necessrio se preocupar com isso, a menos que uma funo recursiva seja
executada de forma desenfreada. A principal vantagem das funes recursivas a
possibilidade de utiliz-Ias para criar verses mais claras e simples de vrios algoritmos, embora uma soluo no recursiva envolvendo outras estruturas (pilhas,
filas etc.) seja mais difcil de desenvolver e mais propensa a erros. Dessa forma,
ocorre um conflito entre a eficincia da mquina e a do programador. O custo
da programao est aumentando e o custo da computao est diminuindo.
Isto leva a um cenrio que no vale a pena para um programador demandar
muito tempo para elaborar programas iterativos quando solues recursivas
podem ser escritas mais rapidamente. Somente deve-se evitar o uso de solues
recursivas que utilizam recurso mltipla (Fibonacci, por exemplo).
5.9 Exerccios
1. Determine o que a seguinte funo recursiva em C calcula. Escreva
uma funo iterativa para atingir o mesmo objetivo:
int func(int
5.8 Vantagens
putsto), }
Fatorial: O!
=O
={"
X
+
11
n
_n
(
)
{
n)
if( n == O)
Nmeros Triangulares: n = 1
Seqncia de Fibonacci: fib(l)
= 1 e fib(2)
return O;
return (n- funcfn-Ij),
'I
78
B Lista
"Existem
b) an,n)
a(111-1,1)Se m
c) a(m,n)
a(m-1, a(m,n-1 Se m
1 Se m
O,
<>
Oen
<>
O,
Oen
<>
o que aconteceu:'
Provrbio
escocs