Post on 08-Feb-2019
FILAS (Queues)
-Estrutura linear de acesso seqüencial que ordena seuselementos pela seqüência cronológica de sua entrada;
-Estrutura FIFO (First In First Out) a ordem de saída é amesma ordem de entrada (o 1o a chegar será o 1o a sair dafila);
-Diferentemente da pilha uma fila pode ser manipulada pelasduas extremidades, conhecidas como FRENTE e CAUDA (oufrente e cauda, etc);
- Restrições quanto à manipulação: inserções sempre no final,remoções sempre do início da fila;
FI LA ESTÁTI CA ( tamanho máximo estático)COM DESCRI TOR
1) I mplementação Simplestypedef struct {
void * vet; int tamVet;
int frente; / * indexa o início da fila * / int cauda; /* indexa o final da fila * / } Fila;
Inserções incrementam a CAUDA, remoções incrementam aFRENTE (CAUDA e FRENTEvariando);
a) Inicialização: CAUDA = -1, FRENTE = 0;b) Tamanho da Fila = CAUDA – FRENTE + 1;c) Fila vazia : CAUDA < FRENTE;d) Fila cheia : CAUDA = = ComprimentoDoVetor - 1; (?!)
Com
o um
Tip
o de
Dad
os A
bstr
ato,
a f
ila,
além
do
mod
elo
de d
ados
, te
rá q
ue p
rove
r um
con
junt
o de
oper
açõe
s.
Ope
raçõ
es:
int
cria
(ppF
ila p
p, in
t ta
mV
et, i
nt t
amIn
fo);
int
busc
aNaF
rent
e(pF
ila p
, voi
d *p
Reg
);in
t in
sere
(pFi
la p
, voi
d *n
ovo)
;in
t re
tira
(pFi
la p
);vo
id d
estr
oi(p
pFila
pp)
;vo
id p
urga
(pFi
la p
);in
t te
staV
azia
(pFi
la p
);in
t te
staC
heia
(pFi
la p
);
Pod
e se
r fl
exib
iliza
do
Ope
raçõ
es d
e in
serç
ão e
rem
oção
par
a a
impl
emen
taçã
o si
mpl
es:
int
inse
reN
aFila
(pFi
la p
, pIn
fo n
ovo)
fila
che
ia ?
SIM
: FR
AC
ASS
O;
NÃ
O: i
ncre
men
ta C
AU
DA
;in
sere
o n
ovo
item
na
posi
ção
inde
xada
por
CA
UD
A;
SUC
ESSO
;
int
rem
oveD
aFila
(pFi
la p
)fi
la v
azia
?SI
M: F
RA
CA
SSO
;N
ÃO
: inc
rem
enta
FR
ENTE
;SU
CES
SO;
SI MULAÇÃO - (1) Fila Estática Simples
Perceba que a implementação da Fila Simples podelevar a inconsistências.Ex: Na linha j, a fila está cheia (CAUDA = = tamVet-1)e vazia (CAUDA < FRENTE) ao mesmo tempo.
Para otimizar o uso do vetor serão propostas trêsadaptações à fila simples: duas utilizandomovimentação de dados e uma utilizando o conceito devetor circular.
Isso ocorre por que a fila SIMPLESnão ocupa o vetor de maneiraótima.
2)Movimentação de Dados a cada remoçãoA cada remoção move-se toda a fila na direção do seu FRENTEde forma a preencher o espaço deixado pela remoção:
(Pseudo código)retira( )if(p-> CAUDA < p-> FRENTE) /* Fila Vazia ?* /
FRACASSO /* SIM * / else / * compactação/remoção FRENTE sempre em zero * /
for (i= 0; i < p-> CAUDA; i+ + ) p-> vetFila[ i] = p-> vetFila[ i+ 1] ;p-> CAUDA--;SUCESSO
a) Tamanho da fila à CAUDA - FRENTE + 1 = CAUDA - 0 + 1= CAUDA+ 1;b) Inicialização: CAUDA = -1, FRENTE = 0;c) Fila vazia : CAUDA < FRENTE;d) Fila cheia : CAUDA = comprimentoDoVetor - 1
SI MULAÇÃO - (2) Fila Estática com Mov. Dados na Remoção
Na Adaptação da Simples (1) para a Fila Estática com Mov. Dados naremoção (2)
Perceba que a frente da fila agora está sempre fixa em zero,portanto, em relação á fila simples:
a)Pode-se eliminar o campo “frente” da estrutura interna doTDA (implicitamente zero).
b)Deve-se adaptar convenientemente as operações quefazem acesso ao campo “frente”.
3) Movimentação de dados na hora certa
FRENTE variável, como feito na alternativa 1, aliado à compactaçãocomo em 2.Ao invés da compactação ocorrer a cada remoção, ela ocorrerá quando,durante a inserção, for detectado um falso sinal de “fila cheia” :(Pseudo código)inserção( )
/ * fila cheia: CAUDA= = comprimentoDoVetor-1 * /Se (CAUDA= = comprimentoDoVetor-1 ) tamanhoDaFila: CAUDA - FRENTE + 1; Se( tamanhoDaFila < comprimentoDoVetor)
for( i= 0; i < tamanhoDaFila; i+ + ) vetFila[ i] = vetFila[ i+ FRENTE];
p-> CAUDA = p-> CAUDA - p-> FRENTE; p-> FRENTE = 0;
Senão / * a FI LA realmente está cheia ! * / Return FRACASSO;
inserção no final da fila; return SUCESSO;
SI MULAÇÃO - (3) Fila Estática com Mov. Dados na I nserção
Independentemente da opção 2 ou 3, amovimentação de dados pode ser uma operaçãobastante lenta.
Se a estrutura possuir N posições e a filade dados possuir N-1 elementos, serãonecessárias N-2 movimentos, dos N-2elementos desde o final da fila.
A solução ideal para implementação de filas estáticaé aquela que otimiza a utilização do espaço da filasem a necessidade de movimentação de dados.
Isso é possível com uma implementação circular
4) Fila Circular
Vetor como um arranjo circular, como se o seu final seligasse ao seu início.
A fila se estende de FRENTE até CAUDA no sentido horário.
A implementação circular para a fila estática é bastantevantajosa, pois reutiliza as posições desocupadas do vetorsem a necessidade de movimentação de dados.
Porém há conseqüências:
•CAUDA< FRENTE não necessariamente implicará em filavazia•O tamanho da fila não necessariamente= = CAUDA-FRENTE + 1
J ) K )
vetFila[ 5 ]F C0 1 2 3 4
operação Interpretação
J)2 4 ... ... X0 X1 X2 ..... ......
K)2 0 X3 ... X0 X1 X2 insere
X3 emmodoFila
circular
fim < inicio à porém afila Não está vazia
tam. da Fila=0-2+1= -1Ã inconsistente
E agora...Se CAUDA < FRENTE nem sempre implicará em fila VAZIAe CAUDA-FRENTE+ 1 nem sempre será = tamanhoDaFila
Como avaliar as condições VAZIA/CHEIA ?
O mais simples é acrescentar tamanhoDaFila como umcampo da estrutura interna do TDA, o qual servirá paradefinir se o estado da fila é vazia ou cheiaindependentemente de FRENTE e CAUDA.
a) Inicialização: CAUDA = -1, FRENTE = 0;b)Tamanho da fila à dado explicito no descritor;c) Fila vazia : tamanho da fila = 0;d) Fila cheia : tamanho da fila = comprimentoDoVetor
Estrutura da Fila CircularEstática:
typedef struct { void * vet; int tamVet; int FRENTE; int CAUDA; int tamanhoDaFila; / * quantidade de dados * / } Fila;
SI MULAÇÃO - (4) Fila Estática - Considerando um Vetor Circular
Para a Fila circular serão necessáriasnovas implementações para:
1) remoção e inserção paraconsiderando-se a “circularidade” dovetor
2) testaVazia e testaCheia onde pode-se tirar proveito do campo “tamanho dafila”
inserção( ) / * pseudo código* /SE ( tamanho atual da fila < tamanho do vetor) / * há espaço no início do vetor * / SE (CAUDA = = tamanho do vetor-1) / * utilize o aspecto circular * /
CAUDA = 0; vetor[CAUDA] = novo; SENÃO vetor[+ + CAUDA] = novo tamanho atual da fila + +SENÃO fila realmente cheia!!
Alternativa p/ controle da “circularidade”:
SE (CAUDA = = tamanhoDovetor - 1)
CAUDA = (CAUDA+ 1)% tamanho do vetor
vetor[CAUDA] = novo
tamanho atual da fila + +
Sentido da
circulação
Remoção( ) / * pseudo código* /
SE(tamanho da fila = = 0)fila vazia
SENÃO SE (FRENTE = = tamanho do vetor-1) FRENTE = 0 SENÃO FRENTE+ +
tamanho da fila - -
Alternativa p/ controle da “circularidade”:
SENÃO
FRENTE = (FRENTE+ 1)% tamanho dovetor
tamanhoDaFila - -
Sentido da
circulação