devly
Voltar para Algoritmos

Estruturas Lineares: Linked Lists, Pilhas e Filas

Vá além dos arrays e domine Linked Lists para inserções eficientes, Pilhas para o princípio LIFO e Filas para o FIFO. Ferramentas essenciais no seu arsenal.

Atualizado em: 10 de Junho, 2025
Notas do Autor

Por muito tempo, eu me perguntava: "pra que raios eu usaria uma Linked List se já existem Arrays?". Arrays são nativos, parecem mais simples e resolvem quase tudo. Essa dúvida persistiu até eu cair numa entrevista onde o problema era implementar um LRU Cache (Least Recently Used Cache).

Tentei resolver com um Array e a performance da minha solução foi péssima. Cada vez que um item era acessado, eu tinha que movê-lo para o final do array, uma operação O(n). Foi aí que o entrevistador deu a dica: "E se a inserção e remoção no início da lista fossem... instantâneas?".

A ficha caiu. Era um caso de uso clássico para Linked Lists. Esta aula é sobre te dar essas "fichas". Vamos entender essas estruturas que parecem de nicho, mas que são as ferramentas perfeitas para problemas específicos que adoram aparecer em entrevistas.


1. Além dos Arrays: Ferramentas Especializadas

Se Arrays são o seu canivete suíço, pense em Linked Lists, Pilhas e Filas como ferramentas especializadas: uma chave de fenda, um alicate e um martelo. Você não os usa para tudo, mas para a tarefa certa, eles são imbatíveis.


2. Linked Lists (Listas Ligadas): A Corrente de Dados 🔗

Diferente de um Array, que armazena dados em um bloco contínuo de memória, uma Linked List é uma coleção de nós (nodes) espalhados pela memória. Cada nó contém duas informações: o dado em si e um ponteiro (uma referência) para o próximo nó da sequência.

Analogia: Caça ao Tesouro 🗺️

Pense em uma caça ao tesouro. Cada pista (nó) te dá uma informação (o dado) e a localização da próxima pista (o ponteiro `next`). Você só precisa saber onde está a primeira pista (o `head` da lista) para percorrer todo o caminho.

Arrays vs. Linked Lists: Os Trade-offs

OperaçãoArrayLinked List
Acesso por Índice (get(i))O(1)O(n)
Inserção/Deleção no InícioO(n)O(1)
Inserção/Deleção no FinalO(1) (amortizado)O(n) (Singly) / O(1) (Doubly)

Resumo: Use Arrays quando precisar de muito acesso rápido por índice. Use Linked Lists quando precisar fazer muitas inserções ou remoções no início da lista.


3. Pilhas (Stacks): O Princípio LIFO 🥞

Uma Pilha segue o princípio LIFO: Last-In, First-Out (O último a entrar é o primeiro a sair).

Analogia: Pilha de Pratos 🍽️

É a analogia perfeita. Você sempre coloca um prato novo no topo e, quando precisa de um, pega o do topo. O primeiro prato que você colocou será o último a ser pego.

As operações principais são todas O(1):

Push: Adiciona um item no topo.
Pop: Remove e retorna o item do topo.
Peek (ou Top): Olha o item do topo sem removê-lo.

Caso de Uso Clássico: Parênteses Balanceados

Um problema comum em entrevistas é verificar se uma string de parênteses, colchetes e chaves está "balanceada". Uma pilha é a solução perfeita para isso.

javascript
function ehValido(s) { // s é uma string como "()[]{}"
  const stack = [];
  const map = {
    "(": ")",
    "[": "]",
    "{": "}",
  };

  for (let i = 0; i < s.length; i++) {
    const char = s[i];

    if (map[char]) {
      // Se o caractere é de abertura, empilha ele.
      stack.push(char);
    } else {
      // Se é de fechamento...
      // 1. Pega o último de abertura que foi empilhado.
      const lastOpen = stack.pop();

      // 2. Verifica se o caractere atual fecha o último que foi aberto.
      if (char !== map[lastOpen]) {
        return false;
      }
    }
  }

  // 3. No final, a pilha deve estar vazia.
  return stack.length === 0;
};

// ehValido("()[]{}") -> true
// ehValido("([)]") -> false
// ehValido("{[]}") -> true

4. Filas (Queues): O Princípio FIFO 🛒

Uma Fila, por outro lado, segue o princípio FIFO: First-In, First-Out (O primeiro a entrar é o primeiro a sair).

Analogia: Fila de Supermercado 🛒

Exatamente isso. A primeira pessoa que chega na fila do caixa é a primeira a ser atendida e a sair.

As operações principais também são O(1) (com a implementação correta):

Enqueue (ou Add): Adiciona um item no final da fila.
Dequeue (ou Remove): Remove e retorna o item do início da fila.
Peek: Olha o primeiro item da fila sem removê-lo.

Filas são muito usadas em algoritmos de busca em grafos (como o BFS, que veremos mais à frente), no gerenciamento de tarefas assíncronas, e em sistemas de mensageria.


💊 Pílula Devly

Arrays são seu canivete suíço, mas para tarefas específicas, você precisa da ferramenta certa. Linked Lists brilham em inserções/remoções sequenciais. Pilhas são perfeitas para problemas de "ida e volta" ou "último a entrar, primeiro a sair" (LIFO). Filas são para ordem de chegada (FIFO). Saber qual usar é um sinal de que você pensa como um arquiteto de soluções, não apenas como um codificador.

Anterior

Os Blocos Fundamentais: Arrays, Strings e Hash Tables

Voltar

Próximo

A Arte da Busca e Ordenação

Continuar