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ção | Complexidade | Notas |
|---|---|---|
| Enfileirar | O(1) | Escreve no fim e avança o índice do fim. |
| Desenfileirar | O(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. |
| Buscar | O(n) | Não é para isso que serve uma fila: você precisa esvaziá-la para olhar dentro. |
| Espaço | O(n) | Um espaço para cada valor esperando. |
Passo a passo
| Passo | O que acontece |
|---|---|
| 1 | A fila começa vazia, com a frente e o fim apontando para o mesmo espaço. |
| 2 | Enfileirar escreve o valor no fim e depois avança o fim em uma posição. |
| 3 | Cada novo enfileiramento cai atrás dos valores que já estão esperando. |
| 4 | Desenfileirar lê o valor da frente e depois avança a frente em uma posição. |
| 5 | O valor que volta é sempre o que esperou mais tempo. |
| 6 | Quando 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ção | Fila (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 quando | Evite quando |
|---|---|
| O trabalho precisa ser tratado por ordem de chegada: filas de jobs, buffers de requisições, spoolers de impressão | Você precisa do item mais recente primeiro, que é um Stack (pilha) |
| Você está explorando nível a nível, como faz a busca em largura | Os 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 eles | Você precisa buscar ou indexar no meio dos dados |
Você quer inserção e remoção O(1) sem deslocar elementos | Você 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
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)Código de Queue em JavaScript
1// A plain array makes dequeue O(n): shift() moves every element left.2// Track a head index instead, the fix the queue article describes.3const queue = { items: [], head: 0 };4
5function enqueue(value) {6 queue.items.push(value);7}8
9function dequeue() {10 const value = queue.items[queue.head];11 queue.items[queue.head] = undefined; // free the slot12 queue.head += 1;13 // Reclaim space once the consumed prefix dominates.14 if (queue.head * 2 >= queue.items.length) {15 queue.items = queue.items.slice(queue.head);16 queue.head = 0;17 }18 return value;19}20
21const size = () => queue.items.length - queue.head;22
23for (const value of [3, 7, 5]) {24 enqueue(value);25 console.log(`enqueue ${value} -> size ${size()}`);26}27
28// Dequeue from the front: first in, first out, amortized O(1)29while (size() > 0) {30 console.log(`dequeue ${dequeue()} -> size ${size()}`);31}32
33console.log('empty:', size() === 0);Código de Queue em Java
1import java.util.ArrayDeque;2import java.util.Queue;3
4public class Main {5 public static void main(String[] args) {6 Queue<Integer> queue = new ArrayDeque<>();7
8 // Enqueue three values at the rear9 for (int value : new int[] {3, 7, 5}) {10 queue.add(value);11 System.out.println("enqueue " + value + " -> " + queue);12 }13
14 // Dequeue them from the front: first in, first out15 while (!queue.isEmpty()) {16 int value = queue.remove();17 System.out.println("dequeue " + value + " -> " + queue);18 }19
20 System.out.println("empty: " + queue.isEmpty());21 }22}Código de Queue em C++
1#include <iostream>2#include <queue>3
4int main() {5 std::queue<int> queue;6
7 // Enqueue three values at the rear8 for (int value : {3, 7, 5}) {9 queue.push(value);10 std::cout << "enqueue " << value << " -> size " << queue.size() << "\n";11 }12
13 // Dequeue them from the front: first in, first out14 while (!queue.empty()) {15 int value = queue.front();16 queue.pop();17 std::cout << "dequeue " << value << " -> size " << queue.size() << "\n";18 }19
20 std::cout << "empty: " << std::boolalpha << queue.empty() << "\n";21 return 0;22}Código de Queue em C
1#include <stdio.h>2
3#define CAP 164
5int queue[CAP];6int front = 0;7int rear = 0; /* index of the next free slot */8
9int main(void) {10 int values[3] = {3, 7, 5};11
12 /* Enqueue three values at the rear */13 for (int i = 0; i < 3; i++) {14 queue[rear++] = values[i];15 printf("enqueue %d -> size %d\n", values[i], rear - front);16 }17
18 /* Dequeue them from the front: first in, first out */19 while (front < rear) {20 int value = queue[front++];21 printf("dequeue %d -> size %d\n", value, rear - front);22 }23
24 printf("empty: %d\n", front == rear);25 return 0;26}Perguntas frequentes sobre filas
O que significa FIFO?
Qual é a diferença entre uma fila e uma pilha?
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?
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?
n continua funcionando indefinidamente em vez de sair do fim do array.