FILAS (Queues)
-Estrutura linear de acesso seqüencial que ordena seus
elementos pela seqüência cronológica de sua entrada;
-Estrutura FIFO (First In First Out) a ordem de saída é a
mesma ordem de entrada (o 1o a chegar será o 1o a sair da
fila);
-Diferentemente da pilha uma fila pode ser manipulada pelas
duas extremidades, conhecidas como inicio e fim (ou frente e
cauda, etc);
- Restrições quanto à manipulação: inserções sempre no final,
remoções sempre do início da fila;
FILA ESTÁTICA (SOBRE UM VETOR) C/ DESCRITOR
1) Sem compactação
typedef struct {
void **vetFila;
int comprimentoDoVetor;
int tamInfo; /* tamanho da informação */
int inicio;
/*indexa o início da fila */
int fim;
/*indexa o final da fila */
} Fila;
Inserções incrementam o FIM, remoções incrementam o INICIO
(INICIO e FIM variando);
a) Inicialização: FIM = -1, INICIO = 0;
b) Tamanho da Fila = FIM – INICIO + 1;
c) Fila vazia : FIM < INICIO;
inicio fim
a)
b)
0
0
-1
-1
c)
d)
e)
f)
g)
h)
...
)
0
0
0
1
2
3
...
2
0
1
2
2
2
2
...
3
vetFila[ 4 ]
0 1 2 3
X0
X0 X1
X0 X1 X2
X1 X2
X2
...
...
... ...
Y m Yn
Interpretação
fila recém criada
tentativa de
remoção  ERRO:
fila vazia
inseriu X0
inseriu X1
inseriu X2
removeu
removeu
removeu
...
tentativa de
inserção  ERRO
(?!?!): fila cheia ???
2) Compactando a Fila — Movimentação de Dados
A cada remoção move-se toda a fila na direção do seu inicio de
forma a preencher o espaço deixado pela remoção:
for (i=0; i < tamanhoFila; i++)
memcpy(p->vetFila[i],p->vetFila[i+1],p->tamInfo);
p->final -= p->inicio;
p->inicio = 0;
Portanto: As inserções incrementam o FIM mas o INICIO fica
fixo no início do vetor (zero);
a) Tamanho da fila  FIM - INICIO + 1 = FIM - 0 +1 =
FIM+1;
b) Inicialização: FIM = -1, INICIO = 0;
c) Fila vazia : FIM < INICIO;
d) Fila cheia : FIM = comprimentoDoVetor - 1
inicio fim
0
a)
b)
c)
d)
e)
f)
g)
h)
i)
vetFila[4]
1
2
3
0
0
0
0
-1
0
1
2
2
X0
X0
X0
0
1
X1
X2
0
0
2
2
X1
X2
X2
0
1
X2
X3
0
0
2
3
X2
X2
X3
X3
X1
X1
X1
X2
X2
X3
X3
X4
X4
X5
Interpretação
fila recém criada
inseriu X0
inseriu X1
inseriu X2
removeu e
compactou
(moveu fila à
esquerda)
inseriu X3
removeu e
compactou
(moveu fila à
esquerda)
inseriu X4
inseriu X5 
fila realmente
cheia !!!!!!
3) Solução híbrida - Compactando na hora certa
INICIO variável, como feito na alternativa 1, aliado à compactação
como em 2.
Ao invés da compactação ocorrer a cada remoção, o critério para
realiza-la seria detectar um falso sinal de “fila cheia”:
inserção( )
/* fila cheia fim== comprimentoDoVetor-1 */
Se (fila cheia)
/* tamanhoDaFila = FIM - INICIO + 1 */
Se(tamanhoDaFila < comprimentoDoVetor)
for(i=0; i < tamanhoDaFila; i++)
memcpy(p->vetFila[i],p>vetFila[i+inicio],p->tamInfo);
p->final -= p->inicio;
p->inicio = 0;
inserção no final da fila;
Senão
FILA realmente cheia;
inicio fim
0
a)
b)
0
0
-1
-1
c)
d)
e)
f)
0
0
0
0
1
2
2
0
0
0
1
2
3
3
3
3
1
1
g)
h)
i)
X0
X0
X0
X0
X2
X2
vetFila[4]
1
2
3
X1
X1
X1
X1
X3
X3
X2
X2
X2
X2
X2
X4
X3
X3
X3
X3
Interpretação
fila recém criada
remoção 
ERRO: fila vazia
inseriu X0
inseriu X1
inseriu X2
inseriu X3
removeu
removeu
inserção X4:
compactou e
insere
Independentemente da opção 2 ou 3, a
compactação da Fila pode ser uma operação
bastante lenta.
Se a estrutura possuir N posições e a
fila de dados possuir N-1 elementos,
serão necessárias N-2 movimentos,
dos N-2 elementos desde o final da
fila.
4) Fila Circular
Considera o vetor como um arranjo circular, como se o
seu final se ligasse ao seu início, não havendo
interrupção.
Na implementação sobre um vetor (ESTÁTICA) a fila
circular torna-se bastante vantajosa, pois viabiliza a
reutilização das posições desocupadas sem a
necessidade de movimentação de dados.
CONSEQÜÊNCIA:
FIM < INICIO NÃO MAIS IMPLICA EM FILA VAZIA
inicio fim
2
5
2
0
vetFila[ 6 ]
0 1 2 ... 5
.... .... X0 ... X3
operação
Interpretação
.....
......
J)
K)
J)
X4 .... X0 ... X3 insere X4 fim < inicio fila Não
em modo
vazia
Fila circular
K)
Aqui consideraremos que a partir do INICIO alcança-se o FIM
explorando a fila no sentido horário: X0,X1,X2,X3,X4
E agora...
Se FIM < INICIO não mais implica em fila VAZIA !
Como testar tal condição ?
Acrescentando-se um campo tamanhoDaFila à
estrutura interna do TDA fila, o qual serviria como
parâmetro para definir se o estado da fila é vazia ou
cheio independentemente de INICIO e FIM.
a) Inicialização: FIM = -1, INICIO = 0;
b)Tamanho da fila  dado explicito na estrutura;
c) Fila vazia : tamanho da fila = 0;
d) Fila cheia : tamanho da fila = comprimentoDoVetor
Estrutura Fila Circular Estática:
typedef struct {
void **vetFila;
int comprimentoDoVetor;
int tamInfo;
int inicio; /* indexa o início da Fila */
int fim; /*indexa o final da Fila */
int tamanhoDaFila; /* testes de vazia/cheia */
} Fila;
inicio
fim tamanho
0
a)
b)
c)
d)
e)
f)
g)
h)
i)
j)
k)
0
0
0
0
1
1
2
3
3
3
3
-1
0
1
2
2
3
3
0
1
2
2
0
1
2
3
2
3
2
1
2
4
4
l)
m)
n)
o)
0
1
2
3
2
2
2
2
3
2
1
0
X0
X0
X0
X4
X4
X4
X4
X4
vetFila[ 4 ]
1
2
3
X1
X1
X1
X1
X5
X5
X5
X5
X5
X2
X2
X2
X2
X6
X6
X6
X6
X6
X3
X3
X3
X3
X3
X3
Interpretação
fila recém criada
inseriu X0
inseriu X1
inseriu X2
removeu
inseriu X3
removeu
inseriu X4
inseriu X5
inseriu X6
inserção X7 
ERRO: fila CHEIA
removeu
removeu
removeu
removeu:
tamanho = 0 
fila VAZIA !!!
inserção( )
SE (tamanho atual da fila < tamanho do vetor)
/* há espaço no início do vetor */
SE (FIM = = tamanho do vetor-1)
/* utilize o aspecto circular */
FIM = 0;
memcpy(p->vetFila[FIM],novo,p->tamInfo);
SENÃO
memcpy(p->vetFIla[++FIM],novo,p->tamInfo);
tamanho atual da fila ++
SENÃO
fila realmente cheia!!
Alternativa p/ controle da “circularidade”:
Sentido da
circulação
SE (FIM == tamanhoDovetor - 1)
FIM = (FIM+1)%tamanho do vetor
vetor[FIM] = novo
tamanho atual da fila ++
Remoção( )
SE(tamanho da fila = = 0)
fila vazia
SENÃO
SE (INICIO = = tamanho do vetor)
INICIO = 0
SENÃO
INICIO++
tamanho da fila - Alternativa p/ controle da “circularidade”:
SENÃO
Sentido da
circulação
INICIO = (INICIO+1)%tamanho do vetor
tamanhoDaFila - -
(Outra alternativa para gerenciar inicio/fim na fila circular)
b) Abrir mão de um espaço na fila fazendo INICIO ser
sempre uma posição antes do inicio real da Fila, então:
se INICIO = = FIM => fila vazia como em (a);
se (FIM+1) = = INICIO => fila cheia como em (m);
inicio fim
a)
b)
0
0
-1
-1
c)
d)
e)
f)
g)
h)
i)
j)
k)
m)
0
0
0
1
1
2
3
3
3
3
0
1
2
2
3
3
3
0
1
1
vetFila[TAM], TAM
== 4
0
1
2
3
X0
X0
X0
X4
X4
X4
X1
X1
X1
X1
X5
X5
X2
X2
X2
X2
X3
X3
X3
X3
X3
X3
Observações
fila recém criada
tentou
uma
remoção => ERRO:
fila vazia
inseriu X0
inseriu X1
inseriu X2
remoção
inseriu X3
remoção
remoção
inseriu X4
inseriu X6
tentou a inserção
X6 => ERRO: fila
cheia
inserção e remoção para Fila Circular como em (B):
remocao( )
insercao( )
if (FIM= =INICIO)
if(FIM == MAX-1)
erro fila vazia
FIM = 0;
else
else
if( INICIO= = MAX-1)
FIM++;
INICO = 0;
if ((FIM +1) = = INICIO)
else
erro fila cheia
INICIO++;
else
memcpy(fila[FIM],novo,tamInfo);
Download

fila cheia