Menu
Coddy logo textTech

Queue (fila)

Última atualização

Uma fila tem duas extremidades ativas. Os valores novos entram pelo fim e os valores saem pela frente, então quem esperou mais tempo é atendido primeiro. Isso é FIFO, e é exatamente como uma fila de atendimento se comporta: entrar por trás e ser atendido pela frente é o que torna a espera justa. Pressione reproduzir acima e veja os valores entrarem por um lado e saírem pelo outro.

Como cada extremidade é controlada pelo seu próprio índice ou ponteiro, as duas operações são O(1) e nenhuma delas desloca o resto dos dados. É por isso que as filas ficam embaixo de tudo que processa trabalho por ordem de chegada: trabalhos de impressão, filas de tarefas e de mensagens, buffers de requisições e a busca em largura, que visita um grafo nível a nível justamente porque mantém sua fronteira em uma fila. Mova para o fim a extremidade de remoção e o que você tem é um Stack (pilha).

Complexidade de tempo e espaço

Para uma fila apoiada em um buffer circular ou em uma lista ligada, as duas implementações padrão:

OperaçãoComplexidadeNotas
EnfileirarO(1)Escreve no fim e avança o índice do fim.
DesenfileirarO(1)Lê na frente e avança o índice da frente, sem deslocar nada.
Peek (frente)O(1)Lê o valor da frente sem removê-lo.
BuscarO(n)Não é para isso que serve uma fila: você precisa esvaziá-la para olhar dentro.
EspaçoO(n)Um espaço para cada valor esperando.

Passo a passo

PassoO que acontece
1A fila começa vazia, com a frente e o fim apontando para o mesmo espaço.
2Enfileirar escreve o valor no fim e depois avança o fim em uma posição.
3Cada novo enfileiramento cai atrás dos valores que já estão esperando.
4Desenfileirar lê o valor da frente e depois avança a frente em uma posição.
5O valor que volta é sempre o que esperou mais tempo.
6Quando a frente encontra o fim a fila está vazia de novo, e continuar desenfileirando é um erro.

Exemplo resolvido

Enfileirando 3, 7, 5 e depois esvaziando a fila:

OperaçãoFila (da frente ao fim)Retorna
enqueue(3)[3]nada
enqueue(7)[3, 7]nada
enqueue(5)[3, 7, 5]nada
dequeue()[7, 5]3, o valor mais antigo
dequeue()[5]7
dequeue()[]5, o valor mais novo, por último

Quando usar uma fila

Use quandoEvite quando
O trabalho precisa ser tratado por ordem de chegada: filas de jobs, buffers de requisições, spoolers de impressãoVocê precisa do item mais recente primeiro, que é um Stack (pilha)
Você está explorando nível a nível, como faz a busca em larguraOs itens precisam ser atendidos por prioridade e não por chegada, onde um heap se encaixa
Um produtor e um consumidor rodam em velocidades diferentes e precisam de um buffer entre elesVocê precisa buscar ou indexar no meio dos dados
Você quer inserção e remoção O(1) sem deslocar elementosVocê a implementaria deslocando um array a cada desenfileiramento, o que a torna O(n)

Código de Queue

Uma implementação limpa e executável de Queue em Python, JavaScript, Java, C++, C. Escolha uma linguagem, copie o código ou abra-o já carregado no Playground da Coddy.

Código de Queue em Python

Python
1from collections import deque2
3queue = deque()4
5# Enqueue three values at the rear6for value in [3, 7, 5]:7    queue.append(value)8    print(f"enqueue {value} -> {list(queue)}")9
10# Dequeue them from the front: first in, first out11while queue:12    value = queue.popleft()13    print(f"dequeue {value} -> {list(queue)}")14
15print("empty:", len(queue) == 0)
Execute este código no Playground de Python

Perguntas frequentes sobre filas

O que significa FIFO?
Primeiro a entrar, primeiro a sair: o valor que esperou mais tempo é o próximo a ser atendido. A fila de uma bilheteria é a imagem do dia a dia. Um Stack (pilha) segue a disciplina oposta, LIFO.
Qual é a diferença entre uma fila e uma pilha?
Apenas a extremidade de onde você remove. As duas adicionam no fim em O(1); uma fila remove pela frente (FIFO), uma pilha remove pela mesma extremidade em que adicionou (LIFO). No resto, as tabelas de complexidade são idênticas.
Quais são as principais operações de uma fila?
enqueue adiciona um valor no fim, dequeue remove e retorna o valor da frente, peek (ou front) lê a frente sem removê-la, e is_empty informa se ainda há algo esperando. As quatro são O(1).
Por que desenfileirar é lento se eu uso um array comum?
Porque remover o índice 0 de um array desloca todos os elementos restantes para a esquerda, tornando cada desenfileiramento O(n). As implementações reais evitam isso com um buffer circular que avança um índice de frente, ou com uma lista ligada com um ponteiro para a cabeça. O collections.deque do Python e o ArrayDeque do Java fazem isso por você, enquanto list.pop(0) não faz.
O que é uma fila circular?
É uma fila em um array de tamanho fixo em que os índices de frente e de fim voltam para 0 quando passam do final. Ela reaproveita os espaços liberados pelos desenfileiramentos, então uma fila de capacidade n continua funcionando indefinidamente em vez de sair do fim do array.
Onde as filas são usadas em programas reais?
Filas de tarefas e de mensagens entre serviços, spoolers de impressão e de jobs, buffers de requisições em servidores web, buffers de teclado e de eventos, pipelines produtor-consumidor, e a busca em largura, onde a fila é o que faz a travessia acontecer nível a nível.
Coddy programming languages illustration

Domine algoritmos com a Coddy

COMEÇAR