Você está na página 1de 17

Filas - Fila Circular

Programao Avanada I

FILAS (Queues)
-Estrutura linear de acesso seqencial que mantm seus elementos em seqncia cronolgica de entrada; -Estrutura FIFO (First In First Out) a ordem de sada a mesma ordem de entrada (o 1o a entrar 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); - Restries quanto manipulao: inseres sempre no final, remoes sempre do incio da fila;
2

FILA ESTTICA (SOBRE UM VETOR) C/ DESCRITOR 1) Sem compactao typedef struct { int *vetFila; /* ponteiro para um vetor de inteiros */ int comprimentoDoVetor; /*numero de elementos */ int inicio; /*indexa o incio da fila */ int fim; /*indexa o final da fila */ } Fila; Inseres incrementam o FIM, remoes incrementam o INICIO (INICIO e FIM variando);

a) Inicializao: FIM = -1, INICIO = 0; b) Tamanho da Fila = FIM INICIO + 1; c) Fila vazia : FIM < INICIO; d) Fila cheia (?!): FIM == ComprimentoDoVetor - 1;
3

inicio fim a) b) c) d) e) f) g) h) ... ) 0 0 0 0 0 1 2 3 ... 2 -1 -1 0 1 2 2 2 2 ... 3

vetFila[ 4 ] 0 1 2 3

Interpretao fila recm criada tentativa de remoo ERRO: fila vazia inseriu X0 inseriu X1 inseriu X2 removeu removeu removeu ... tentativa de insero ERRO (?!?!): fila cheia 4 ???

X0 X0 X1 X0 X1 X2 X1 X2 X2 ... ... ... ... Ym Yn

2) Compactando a Fila Movimentao de Dados A cada remoo move-se toda a fila na direo do seu inicio de forma a preencher o espao deixado pela remoo:

for (i=0; i < tamanhoFila; i++) p->vetFila[i]=p->vetFila[i+1]; p->final -= p->inicio; p->inicio = 0;


Portanto: As inseres incrementam o FIM mas o INICIO fica fixo no incio do vetor (zero);

a) Tamanho da fila FIM - INICIO + 1 = FIM - 0 +1 = FIM+1; b) Inicializao: FIM = -1, INICIO = 0; c) Fila vazia : FIM < INICIO; 5 d) Fila cheia : FIM = comprimentoDoVetor - 1

inicio fim 0 a) b) c) d) e) 0 0 0 0 -1 0 1 2 2 1 2 2 1 2 3 X0 X0 X0

vetFila[4] 1 2 3

Interpretao fila recm 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 6 cheia !!!!!!

X1 X1 X1 X2 X2 X2 X3 X3 X3

X2 X2

0 f) g) 0 0 0 h) i) 0 0

X1 X1

X3 X3

X2 X2 X2

X4 X4

X5

3) Soluo hbrida - Compactando na hora certa INICIO varivel, como feito na alternativa 1, aliado compactao como em 2. Ao invs da compactao ocorrer a cada remoo, o critrio para realiza-la seria detectar um falso sinal de fila cheia: insero( ) /* fila cheia fim== comprimentoDoVetor-1 */ Se (fila cheia) /* tamanhoDaFila = FIM - INICIO + 1 */ Se(tamanhoDaFila < comprimentoDoVetor) for(i=0; i < tamanhoDaFila; i++) p->vetFila[i]=p->vetFila[i+inicio]; p->final -= p->inicio; p->inicio = 0; // insero no final da fila; Seno FILA realmente cheia; Seno ..........
7

inicio fim 0 a) b) c) d) e) f) g) h) i) 0 0 0 0 0 0 1 2 2 0 0 -1 -1 0 1 2 3 3 3 3 1 1 X0 X0 X0 X0

vetFila[4] 1 2 3

Interpretao fila recm criada remoo ERRO: fila vazia inseriu X0 inseriu X1 inseriu X2 inseriu X3 removeu removeu insero X4: compactou e insere 8

X1 X1 X1 X1

X2 X2 X2 X2 X2 X4

X3 X3 X3 X3

X2 X2

X3 X3

Independentemente da opo 2 ou 3, a compactao da Fila pode ser uma operao bastante lenta.

Se a estrutura possuir N posies e a fila de dados possuir N-1 elementos, sero necessrias 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 incio, no havendo interrupo. Na implementao sobre um vetor (ESTTICA) a fila circular torna-se bastante vantajosa, pois viabiliza a reutilizao das posies desocupadas sem a necessidade de movimentao de dados.
CONSEQNCIA:
FIM < INICIO NO MAIS IMPLICA EM FILA VAZIA
10

inicio fim 2 J) 2 K) 0 5

vetFila[ 6 ] 0 1 2 ... 5 .... .... X0 ... X3

operao .....

Interpretao ......

X4 .... X0 ... X3 insere X4 fim < inicio fila No em modo vazia Fila circular
K)

J)

Aqui consideraremos que a partir do INICIO alcana-se o FIM 11 explorando a fila no sentido horrio: X0,X1,X2,X3,X4

E agora... Se FIM < INICIO no mais implica em fila VAZIA ! Como testar tal condio ? Acrescentando-se um campo tamanhoDaFila estrutura interna do TDA fila, o qual serviria como parmetro para definir se o estado da fila vazia ou cheio independentemente de INICIO e FIM. a) Inicializao: FIM = -1, INICIO = 0; b)Tamanho da fila dado explicito na estrutura; c) Fila vazia : tamanhoDaFila = 0; d) Fila cheia : tamanhoDaFila = comprimentoDoVetor
12

Estrutura Fila Circular Esttica:


typedef struct { int *vetFila; int comprimentoDoVetor; int inicio; /* indexa o incio da Fila */ int fim; /*indexa o final da Fila */ int tamanhoDaFila; /* testes de vazia/cheia */ } Fila; ...... Fila fi, f*; f=&fi;
13

inicio a) b) c) d) e) f) g) h) i) j) k) l) m) n) o) 0 0 0 0 1 1 2 3 3 3 3 0 1 2 3

fim tamanho 0 -1 0 1 2 2 3 3 0 1 2 2 2 2 2 2 0 1 2 3 2 3 2 2 3 4 4 3 2 1 0 X0 X0 X0

vetFila[ 4 ] 1 2 3

Interpretao fila recm criada inseriu X0 inseriu X1 inseriu X2 removeu inseriu X3 removeu inseriu X4 inseriu X5 inseriu X6 insero X7 ERRO: fila CHEIA removeu removeu removeu removeu: tamanho = 0 fila VAZIA !!! 14

X1 X1 X1 X1

X2 X2 X2 X2

X4 X4 X4 X4 X4

X5 X5 X5 X5 X5

X6 X6 X6 X6 X6

X3 X3 X3 X3 X3 X3

Insero(int novo )

SE(tamanhoDaFila < comprimentoDoVetor) /* h espao no incio do vetor */ SE (f->fim = = f->comprimentoDoVetor-1) /* utilize o aspecto circular */ f->fim = 0; f->vetFila[f->fim]=novo; SENO f->vetFIla[++(f->fim)]=novo; f->tamanhoDaFila ++; SENO /*fila realmente cheia!! */ Alternativa p/ controle da circularidade:
SE (FIM == tamanhoDoVetor - 1)
Sentido da circulao

FIM = (FIM+1) % tamanhoDoVetor; vetor[FIM] = novo; tamanhoDaFila ++;


15

Remoo( )
SE(f->tamanhoDaFila = = 0) //fila vazia SENO SE (f->inicio = =f->comprimentoDoVetor-1) f->inicio= 0; SENO f->inicio++; f-> tamanhoDaFila - -;
Alternativa p/ controle da circularidade:
Sentido da circulao

SENO INICIO = (INICIO+1)% ComprimentoDoVetor; tamanhoDaFila - -;


16

(Outra alternativa para gerenciar inicio/fim na fila circular)

b) Abrir mo de um espao na fila fazendo INICIO ser sempre uma posio antes do inicio real da Fila, ento:
se INICIO = = FIM => fila vazia como em (a); se (FIM+1) = = INICIO => fila cheia como em (m);

17

Você também pode gostar