<Direto ao Ponto 50> Estruturas de Dados - Filas
Artigos desta série: ( < ) Anterior | Índice | Seguinte ( > )
Olá, dev!
Este é mais um artigo da série DIRETO AO PONTO, que eu estou escrevendo para a DIO. Ele vai tratar de uma das principais estruturas de dados, as filas.
Sumário
1. Introdução
2. As filas
3. Exemplos de aplicações implementadas com filas
4. Considerações finais
5. Referências
1 – Introdução
Eu criei a série de artigos DIRETO AO PONTO com o objetivo de apresentar, de forma simples e direta, conhecimentos básicos da programação e de computação, principalmente, para os iniciantes.
Aqui, são tratados de temas como lógica de programação, linguagens, hardware dos computadores, história da computação e assuntos relacionados à plataforma da DIO, como a escrita de artigos e os desafios de código.
Neste artigo, eu vou falar sobre as filas e as aplicações que usam filas na implementação. Dentre estas aplicações, estão os servidores de impressão e servidores web.
2 – As filas
OBS: Recomendo assistir a essa animação divertida [1], do quadro mostrado na figura acima, sobre como as pessoas costumam se comportar em filas do nosso cotidiano (link nas referências).
Da mesma forma que as listas, as filas também são um Tipo Abstrato de Dado (TAD), definição de um modelo matemático para tipos de dados.
Basicamente, um TAD especifica um conjunto de dados e as operações que podem ser realizadas sobre eles, sem tratar da implementação destas operações.
Por exemplo, uma lista de tarefas permite adicionar, remover ou verificar tarefas da lista. O TAD define essas operações (adicionar, remover, verificar), mas não diz como a lista é armazenada ou como essas operações são realizadas internamente. Essa abstração permite que se use a lista sem se preocupar com os detalhes de implementação.
Os TADs são modelos matemáticos que encapsulam dados e operações que podem ser realizadas sobre esses dados, como um objeto. Os mais comuns são:
· Lista (List);
· Fila (Queue);
· Pilha (Stack);
· Conjunto (Set);
· Mapa (Map);
· Dicionário (Dictionary);
· Árvore (Tree);
· Grafo (Graph).
A estrutura de dados fila é usada para armazenar elementos de forma ordenada, seguindo o princípio FIFO (“First In, First Out”), ou seja, o primeiro elemento a entrar é o primeiro a sair.
Este comportamento é útil em várias situações, para gerenciar tarefas em ordem sequencial. Algumas aplicações são listadas a seguir:
· Sistemas de impressão: Gerenciamento de trabalhos de impressão por ordem de chegada;
· Servidores web: Processamento de requisições HTTP;
· Sistemas operacionais: Gerenciamento de processos em sistemas multitarefa.
· Algoritmos de busca em grafos: Implementação de algoritmos como BFS (Busca em Largura).
· Filas de mensagens: Comunicação entre diferentes partes de um sistema distribuído.
Uma fila possui as seguintes características, algumas a diferem claramente de uma lista:
· Uma variável aponta para o primeiro elemento da fila;
· Outra aponta para o último elemento;
· Cada elemento aponta apenas para o próximo da fila (semelhante a uma lista simplesmente encadeada);
· A fila só pode ser varrida a partir do primeiro elemento, indo até o último;
· Um elemento só pode ser inserido na fila na última posição;
· Só o primeiro elemento da fila pode ser removido;
Veja que ela uma fila se comporta como uma lista simplesmente encadeada, com cada elemento apontando para o seguinte. Além disso, ela se comporta como uma lista duplamente encadeada, pois uma segunda variável aponta para o último elemento, embora ela não possa ser percorrida de trás para a frente.
As operações básicas que podem ser realizadas com uma fila são (em pseudo-código, independentemente de alguma linguagem de programação específica:
Criação (ou declaração) – nomeia a variável, informa o tipo e reserva espaço para os elementos:
int fila[10] – declara um vetor de inteiros com 10 posições
int inicio - declara inteiro para o índice do primeiro elemento
int fim - declara inteiro para o índice do novo elemento a inserir
Inicialização – ao declarar a fila, já informar os elementos dela:
int fila = [3, 4, 0, 1, -5, 23 ] – declara um vetor de inteiros com 6 posições
int inicio = -1 - declara inteiro com o índice (-1, nulo) do primeiro elemento
int fim = 0 - declara inteiro com índice (0) da posição de inserção do próximo elemento
Acesso – Só pode ser acessado o valor armazenado na primeira posição da fila, na operação de remoção do primeiro elemento:
elemento = fila[inicio]; // na fila acima, o valor acessado é 3 (primeiro elemento)
print(fila[inicio]) // imprime o valor 3, que era o primeiro elemento da fila acima
Atribuição – não se pode atribuir um valor para nenhuma posição da fila. Além disso, novos elementos só podem ser inseridos no final da fila, após o último elemento presente, numa operação de inserção:
fila[fim] = 9; // atribui o valor 9 à última posição da fila acima, que ficaria [4, 0, 1, -5, 23, 9 ].
Fila vazia – Se a fila não possuir nenhum elemento armazenado, ela estará vazia e a operação de remoção não pode ser realizada.
fila = [ ] – fila sem nenhum elemento (vazia)
Fila cheia – Se a fila usar todo o espaço para inserção de elementos, ela estará cheia e a operação de inserção não pode ser realizada. Este caso pode ocorrer no caso estático de um vetor cheio ou, no caso dinâmico, sistema sem memória para alocação dinâmica.
Para uma fila de 6 elementos, a fila [4, 0, 1, -5, 23, 9 ] está cheia, sem caber novos elementos.
Listar elementos da fila (opcional) – Esta operação (opcional) varre todos os elementos da fila e os lista, seguindo do primeiro ao último elemento.
Tamanho da fila (opcional) - Esta operação (opcional) varre todos os elementos da fila, contando quantos estão armazenados nela.
Limpeza da fila (opcional) - Esta operação (opcional) limpa, de uma vez só, o conteúdo de todos os elementos do vetor para um valor considerado nulo (0, string vazio, null etc.).
Uma fila pode ser implementada de várias maneiras: usando vetor estático, lista encadeada (com ponteiros), com um tipo lista (list) ou por um tipo específica (Queue). Vamos ver um resumo de cada uma delas.
I - IMPLEMENTAÇÃO COM LISTA
É semelhante àquela mostrada no artigo anterior, no qual eu detalhei o uso de listas.
Uma fila só pode ser percorrida do início ao fim (como uma lista simplesmente encadeada) e um novo elemento só pode ser adicionado no final dela, além de só poder ser retirado o primeiro elemento da fila (ver figura a seguir, com a fila inicial).
A fila tem um ponteiro adicional que aponta para o seu elemento final, evitando que toda a fila precise ser percorrida até o elemento final para adicionar um novo elemento após ele. O ponteiro de final de fila já acessa o elemento final.
Assim, para inserir um novo elemento, basta fazer o último elemento da fila apontar (campo prox) para o novo, o campo prox do novo elemento apontar para o valor nulo (indicando que agora ele é o final da fila) e atualizar a variável de final de fila, que apontará para o novo elemento, como novo último da fila.
Se o ponteiro inicial apontar para o valor nulo, significa que a fila está vazia, sem nenhum elemento armazenado, esperando por um novo elemento para poder ser utilizada.
Todo novo elemento será adicionado após o último elemento. Se ele for o primeiro da fila, o ponteiro de início da fila também deverá ser atualizado (ver figura).
Após a inserção do novo elemento, a fila ficaria assim:
Em uma fila, só o primeiro elemento poderá ser removido, significando que ele saiu para ser usado, passando o segundo elemento a ser o novo primeiro elemento da fila. Com base na figura da fila inicial, abaixo é mostrada a operação de remoção do primeiro elemento:
E a fila ficará assim:
OBS: na verdade, um elemento removido não é apagado, ele continua armazenado na estrutura do nó, no mesmo endereço alocado na sua criação, apenas não será mais acessado por nenhum ponteiro (campo prox) da fila.
II - A IMPLEMENTAÇÃO COM VETOR ESTÁTICO
Segue o modelo mostrado no artigo sobre vetores (anterior ao das listas), com diferenças que vou mostrar agora (ver figura da fila):
Basicamente, é preciso criar um vetor com um número determinado de posições, usar duas variáveis para determinar os índices do primeiro elemento da fila e da posição vaga onde deve ser armazenado um novo elemento. No início, uma fila que acabou de ser criada ficaria assim, vazia:
Cada inserção de um novo elemento será feita na posição indicada pelo índice da variável de final (fim) de fila, que será incrementada de 1 posição (ver figuras com a inserção do primeiro e de um segundo elemento).
Cada remoção de elemento será feita na posição indicada pelo índice da variável de início de fila, que também será incrementada de 1. A figura a seguir mostra a fila após a remoção do elemento 8.
OBS: na verdade, um elemento removido não sai do vetor, ele continuará lá, na mesma posição, apenas não será mais acessado.
Na figura anterior, removendo mais 1 elemento, a fila ficará vazia e nenhum elemento poderá ser removido. Veja que a variável de início agora aponta para o índice 2, não para 0. A situação de fila vazia pode ser identificada quando os valores das variáveis de início e fim da fila tiverem o mesmo valor.
Caso todas as posições do vetor sejam ocupadas, a fila estará cheia e não aceitará mais inserções de elementos. A partir da situação da fila da figura anterior, inserindo mais 4 elementos, ela ficaria cheia, assim:
Veja que a fila da figura anterior está cheia, mas ainda existem 2 posições iniciais vazias, que poderiam ser aproveitadas. Para isso, seria preciso trocar todos os elementos de posição, uma operação custosa.
O uso de filas implementadas por vetores só é eficiente quando o vetor é bem maior que a quantidade de elementos que serão inseridos na fila, assim ela não ficaria cheia regularmente, o que evitaria a operação de trocas de posição para aproveitamento das posições vazias.
Mesmo assim, filas implementadas com vetores são muito simples e didáticas para um ensino inicial do tema.
FILA CIRCULAR
Uma solução criada para evitar muitas posições vazias é a fila circular. Ela junta o final do vetor com seu início, gerando um círculo de posições que se complementam, permitindo que um elemento novo volte a ser inserido no início da fila original. Assim, as posições vagas no início da fila são aproveitadas, a partir da realocação das variáveis de início e fim da fila.
A fila da figura anterior poderia ser representada por uma fila circular da seguinte maneira:
Na fila da figura anterior, o início da fila aponta para a posição de índice 2, enquanto o final da fila aponta para a próxima posição vaga (6, inexistente);
A solução encontrada é apontar o fim da fila para a posição 0 do vetor, criando uma fila circular, mostrada na figura seguinte:
Por exemplo, para inserir um novo elemento (12) na fila, ela (a fila circular) e o vetor correspondente ficariam assim:
Desta forma, a implementação de uma fila circular melhora a da fila com vetor estático, pois aproveita as posições já usadas nas remoções. Mesmo assim, o uso de vetor para implementar filas é muito limitado.
III - A IMPLEMENTAÇÃO USANDO A ESTRUTURA LIST
Uma fila implementada com listas segue as seguintes características:
Uma lista pode ser criada sem nenhum elemento, significando uma fila vazia.
Ex: fila = [ ]
A operação de atribuição de um valor (ou inserção de um elemento) na fila se dá sempre na última posição da lista. Em Python, o método seria append():
para lista = [ 8, -1, 4, 25, 0]:
Ex: list.append(7) insere o valor 7 na última posição, ficando [ 8, -1, 4, 25, 0, 7].
Já a operação de acesso a um valor (ou remoção de um elemento) da fila se dá sempre na primeira posição da lista. Em Python, o método é pop(0).
Ex: para lista = [ 8, -1, 4, 25, 0, 7 ], list.pop(0) exclui o valor (8) da primeira posição resultando em [ -1, 4, 25, 0, 7 ]
A figura a seguir mostra a fila indicada acima após a inserção do 7 e a remoção do 8:
IV - IMPLEMENTAÇÃO USANDO UM TIPO ESPECÍFICO PARA FILA
Segue as seguintes características:
Algumas linguagens oferecem um tipo específico para tratar de filas (queues), com pelo menos 2 métodos para inserir e remover elementos.
Por exemplo, a linguagem C# oferece o tipo Queue<T>, com os métodos:
· Enqueue( ), para adicionar um elemento (enfileirar) no final da fila;
- Dequeue( ), para remover primeiro elemento da fila (desenfileirar).
O tipo Queue<T> ainda oferece outros métodos específicos para manipulação de filas:
· Peek() - Retorna o primeiro elemento da fila sem removê-lo;
· Clear() - Remove todos os elementos da fila, deixando-a vazia;
· Contains(itemT) - Verifica se a fila contém o elemento especificado;
· ToArray() - Converte a fila em array com os elementos, na ordem;
· TrimExcess() - Reduz a capacidade da fila para o número real de elementos, liberando memória;
· GetEnumerator() - Retorna um enumerador para percorrer os elementos da fila;
· Count – Propriedade que retorna o número total de elementos da fila.
3 – Exemplos de aplicações implementadas com fila
A seguir, seguem alguns programas básicos que implementam filas, em linguagens diferentes:
NA LINGUAGEM PASCAL – USANDO VETOR ESTÁTICO
program FilaComVetor;
const
MAX = 4; { Tamanho máximo da fila }
type
TFila = array[1..MAX] of Integer;
var
fila: TFila;
inicio, fim: Integer; { variáveis para início e final da fila }
{ Função para inicializar a fila }
procedure InicializarFila;
begin
inicio := 1;
fim := 0;
end;
{ Função para verificar se a fila está vazia }
function FilaVazia: Boolean;
begin
FilaVazia := (fim < inicio);
end;
{ Função para verificar se a fila está cheia }
function FilaCheia: Boolean;
begin
FilaCheia := (fim = MAX);
end;
{ Procedimento para enfileirar um elemento na fila }
procedure Enfileirar(elemento: Integer);
begin
if FilaCheia then
writeln('A fila está cheia. Não foi possível adicionar ', elemento)
else
begin
fim := fim + 1;
fila[fim] := elemento;
writeln(elemento, ' foi adicionado à fila.');
end;
end;
{ Função para desenfileirar (remover) um elemento da fila }
function Desenfileirar: Integer;
var
removido: Integer;
begin
if FilaVazia then
begin
writeln('A fila está vazia. Não há elementos para remover.');
Desenfileirar := -1; { Retorna -1 para indicar erro }
end
else
begin
removido := fila[inicio];
writeln(removido, ' foi removido da fila.');
inicio := inicio + 1;
Desenfileirar := removido;
end;
end;
{ Procedimento para exibir o estado atual da fila }
procedure MostrarFila;
var
i: Integer;
begin
if FilaVazia then
writeln('A fila está vazia.')
else
begin
writeln('Fila atual: ');
for i := inicio to fim do
write(fila[i], ' ');
writeln;
end;
end;
{ Programa principal }
begin
InicializarFila; { Inicializa a fila }
{ Exemplo de operações na fila }
Enfileirar(10);
Enfileirar(20);
Enfileirar(30);
MostrarFila; { Mostra a fila }
Desenfileirar; { Remove o primeiro elemento }
Desenfileirar; { Remove o segundo elemento }
MostrarFila; { Mostra a fila }
Enfileirar(40); { Tenta adicionar um novo elemento }
MostrarFila; { Exibe o estado final da fila }
Enfileirar(50); { Tenta adicionar um novo elemento }
MostrarFila; { Exibe o estado final da fila }
end.
Saída do programa
10 foi adicionado à fila.
20 foi adicionado à fila.
30 foi adicionado à fila.
Fila atual:
10 20 30
10 foi removido da fila.
20 foi removido da fila.
Fila atual:
30
40 foi adicionado à fila.
Fila atual:
30 40
A fila está cheia. Não foi possível adicionar 50
Fila atual:
30 40
LINGUAGEM C – USANDO LISTA ENCADEADA COM PONTEIROS
#include <stdio.h>
#include <stdlib.h>
// Definição do nó da fila
struct No {
int dado;
struct No* prox;
};
// Estrutura da fila, com ponteiros para o início (inic) e final (fim)
struct Queue {
struct No* inicio;
struct No* fim;
};
// Função para criar uma nova fila vazia
struct Queue* criarFila() {
struct Queue* fila = (struct Queue*)malloc(sizeof(struct Queue));
fila->inicio = fila->fim = NULL;
return fila;
}
// Função para criar um novo nó
struct No* novoNo(int valor) {
struct No* temp = (struct No*)malloc(sizeof(struct No));
temp->dado = valor;
temp->prox = NULL;
return temp;
}
// Função para enfileirar (inserir) um elemento
void enfileirar(struct Queue* fila, int valor) {
// Cria um novo nó
struct No* temp = novoNo(valor);
// Se a fila estiver vazia, o novo nó será o início e o final
if (fila->fim == NULL) {
fila->inicio = fila->fim = temp;
printf("%d foi adicionado à fila.\n", valor);
return;
}
// Adiciona o novo nó no final da fila e atualiza o ponteiro 'rear'
fila->fim->prox = temp;
fila->fim = temp;
printf("%d foi adicionado à fila.\n", valor);
}
// Função para desenfileirar (remover) um elemento da fila
int desenfileirar(struct Queue* fila) {
// Se a fila estiver vazia, retorna um valor inválido
if (fila->inicio == NULL) {
printf("A fila está vazia. Não é possível remover elementos.\n");
return -1;
}
// Armazena o ponteiro do início da fila
struct No* temp = fila->inicio;
int removido = temp->dado;
// Move o ponteiro 'front' para o próximo nó
fila->inicio = fila->inicio->prox;
// Se o 'front' se tornar NULL, a fila está vazia, então atualiza 'rear' também
if (fila->inicio == NULL) {
fila->fim = NULL;
}
// Libera o nó removido
free(temp);
printf("%d foi removido da fila.\n", removido);
return removido;
}
// Função para verificar o próximo elemento da fila
int verificar(struct Queue* fila) {
if (fila->inicio == NULL) {
printf("A fila está vazia.\n");
return -1;
} else {
printf("O próximo elemento é: %d\n", fila->inicio->dado);
return fila->inicio->dado;
}
}
// Função para verificar se a fila está vazia
int filaVazia(struct Queue* fila) {
return fila->inicio == NULL;
}
// Função para exibir o estado atual da fila
void mostrarFila(struct Queue* fila) {
if (filaVazia(fila)) {
printf("A fila está vazia.\n");
} else {
struct No* temp = fila->inicio;
printf("Fila atual: ");
while (temp != NULL) {
printf("%d ", temp->dado);
temp = temp->prox;
}
printf("\n");
}
}
// Programa principal
int main() {
// Cria uma nova fila
struct Queue* minhaFila = criarFila();
// Exemplo de uso da fila
enfileirar(minhaFila, 10); // Adiciona 10 à fila
enfileirar(minhaFila, 20); // Adiciona 20 à fila
enfileirar(minhaFila, 30); // Adiciona 30 à fila
mostrarFila(minhaFila); // Exibe a fila
verificar(minhaFila); // Verifica o próximo elemento
desenfileirar(minhaFila); // Remove 10 da fila
desenfileirar(minhaFila); // Remove 20 da fila
mostrarFila(minhaFila); // Exibe a fila após remoções
desenfileirar(minhaFila); // Remove 30 da fila
mostrarFila(minhaFila); // Exibe a fila final
// Libera a fila ao final do programa
free(minhaFila);
return 0;
}
Saída do programa
10 foi adicionado à fila.
20 foi adicionado à fila.
30 foi adicionado à fila.
Fila atual: 10 20 30
O próximo elemento é: 10
10 foi removido da fila.
20 foi removido da fila.
Fila atual: 30
30 foi removido da fila.
A fila está vazia.
NA LINGUAGEM PYTHON – USANDO O TIPO LIST
# Lista para armazenar os elementos da fila
fila = [ ]
# Função para adicionar um elemento à fila)
def enfileirar(elemento):
fila.append(elemento)
print(f"{elemento} foi adicionado à fila.")
# Função para remover o primeiro elemento da fila)
def desenfileirar():
if fila_vazia():
print("A fila está vazia. Não é possível remover elementos.")
return None
else:
elemento_removido = fila.pop(0) # Remove o primeiro elemento
print(f"{elemento_removido} foi removido da fila.")
return elemento_removido
# Função para verificar o primeiro elemento da fila (sem remover)
def verificar_fila():
if fila_vazia():
print("A fila está vazia.")
return None
else:
print(f"O próximo elemento é: {fila[0]}")
return fila[0]
# Função para verificar se a fila está vazia
def fila_vazia():
return len(fila) == 0
# Função para exibir o estado atual da fila
def mostrar_fila():
if fila_vazia():
print("A fila está vazia.")
else:
print(f"Fila atual: {fila}")
# Exemplo de uso da fila
enfileirar(10) # Adiciona 10 à fila
enfileirar(20) # Adiciona 20 à fila
enfileirar(30) # Adiciona 30 à fila
mostrar_fila() # Exibe a fila atual
verificar_fila() # Verifica o primeiro elemento (10)
desenfileirar() # Remove 10 da fila
desenfileirar() # Remove 20 da fila
mostrar_fila() # Exibe a fila após remoções
desenfileirar() # Remove 30 da fila
desenfileirar() # Tenta remover de uma fila vazia
Saída
10 foi adicionado à fila.
20 foi adicionado à fila.
30 foi adicionado à fila.
Fila atual: [10, 20, 30]
O próximo elemento é: 10
10 foi removido da fila.
20 foi removido da fila.
Fila atual: [30]
30 foi removido da fila.
A fila está vazia. Não é possível remover elementos.
LINGUAGEM C# – USANDO O TIPO ESPECÍFICO QUEUE<T>
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
// Criação da fila usando Queue<int>
Queue<int> fila = new Queue<int>();
// Enfileirar elementos
Enfileirar(fila, 10); // Adiciona 10 à fila
Enfileirar(fila, 20); // Adiciona 20 à fila
Enfileirar(fila, 30); // Adiciona 30 à fila
// Mostrar estado atual da fila
MostrarFila(fila); // Exibe a fila atual
// Verificar o próximo elemento
Verificar(fila); // Verifica o primeiro elemento (10)
// Desenfileirar elementos
Desenfileirar(fila); // Remove 10 da fila
Desenfileirar(fila); // Remove 20 da fila
// Mostrar estado atual da fila
MostrarFila(fila); // Exibe a fila após remoções
// Desenfileirar o restante e verificar fila vazia
Desenfileirar(fila); // Remove 30 da fila
Desenfileirar(fila); // Tenta remover de uma fila vazia
}
// Função para enfileirar um elemento
static void Enfileirar(Queue<int> fila, int elemento)
{
fila.Enqueue(elemento);
Console.WriteLine($"{elemento} foi adicionado à fila.");
}
// Função para desenfileirar um elemento
static void Desenfileirar(Queue<int> fila)
{
if (fila.Count == 0)
{
Console.WriteLine("A fila está vazia. Não é possível remover elementos.");
}
else
{
int elementoRemovido = fila.Dequeue(); // Remove o primeiro elemento
Console.WriteLine($"{elementoRemovido} foi removido da fila.");
}
}
// Função para verificar o próximo elemento da fila
static void Verificar(Queue<int> fila)
{
if (fila.Count == 0)
{
Console.WriteLine("A fila está vazia.");
}
else
{
Console.WriteLine($"O próximo elemento é: {fila.Peek()}");
}
}
// Função para mostrar o estado atual da fila
static void MostrarFila(Queue<int> fila)
{
if (fila.Count == 0)
{
Console.WriteLine("A fila está vazia.");
}
else
{
Console.Write("Fila atual: ");
foreach (int item in fila)
{
Console.Write(item + " ");
}
Console.WriteLine();
}
}
}
Saída
10 foi adicionado à fila.
20 foi adicionado à fila.
30 foi adicionado à fila.
Fila atual: 10 20 30
O próximo elemento é: 10
10 foi removido da fila.
20 foi removido da fila.
Fila atual: 30
30 foi removido da fila.
A fila está vazia. Não é possível remover elementos.
4 – Considerações finais
Este é mais um artigo da série DIRETO AO PONTO, que eu estou escrevendo para a DIO. Neste artigo eu tratei das filas, mais um Tipo Abstrato de Dado (TAD), juntamente com as listas e pilhas.
Uma fila é uma estrutura de dados, como a lista, usada para armazenar elementos de forma ordenada, mas com características de inserção e remoção de elementos. Ela segue o princípio FIFO (“First In, First Out”), no qual o primeiro elemento a entrar é o primeiro a sair.
Elas são apropriadas em aplicações para gerenciar tarefas em ordem sequencial, como em sistemas de impressão, servidores web ou no gerenciamento de processos em sistemas operacionais.
Uma fila pode ser implementada de várias formas, usando vetores estáticos, ponteiros, listas ou estruturas específicas para manipulação de filas, como Queue<T>, da linguagem C#.
Algumas destas formas são bem antigas (vetores), mas continuam em uso por serem muito didáticas, principalmente para os iniciantes em programação, já outras são bem trabalhosas (com ponteiros), pois exigem completo gerenciamento da memória pelo programador.
As formas mais atuais de implementação são usando listas (como em Python) ou estruturas específicas, como a classe Queue<T>, por exemplo.
Neste artigo, foram mostrados os detalhes dos conceitos e das operações usadas para a implementação de filas usando vetores e ponteiros.
Também foram apresentados exemplos de códigos com a implementação de filas usando cada uma das 4 formas citadas anteriormente.
No próximo artigo, vamos falar das pilhas, muito usadas na programação.
5 – Referências
Praticamente todo o conteúdo deste artigo foi tirado do que eu aprendi (e me lembro) sobre o assunto desde o início da minha carreira como programador, desde os anos 80 até agora. Algumas atualizações conceituais foram feitas com a ajuda do ChatGPT e do Copilot.
Para criar os códigos dos exemplos, eu consultei o ChatGPT e fiz algumas correções necessárias para sair do jeito que eu queria. Todos os códigos foram testados e rodaram sem problemas.
[1] - Ferdinand Lutz. Stay in Queue. Disponível em <https://www.youtube.com/watch?v=IPxBKxU8GIQ>. Acessado em: 05/10/2024.
Artigos desta série: ( < ) Anterior | Índice | Seguinte ( > )