Módulo 2 - Pilhas: a estrutura em que o último entra e sai primeiro

Parênteses balanceados com uma pilha

9 min de leitura · por Cesar Gargiulo, revisado pela equipe ValorFinal e GuardiaSec · Atualizado em 12/07/2026

O que você vai aprender

  • Entender o que significa uma expressão ter parênteses balanceados.
  • Usar uma pilha para verificar o balanceamento de abre e fecha.
  • Empilhar cada símbolo de abertura e desempilhar a cada fechamento.
  • Reconhecer as três formas de desbalanceamento e como a pilha detecta cada uma.

O problema dos parênteses

Toda expressão matemática e todo pedaço de código dependem de parênteses, colchetes e chaves bem casados. A conta 2 vezes (3 mais 4) só faz sentido com o parêntese fechado. Um código com um colchete a mais ou a menos nem roda. O problema é: dada uma sequência de abre e fecha, como um programa decide se ela está balanceada? Três coisas podem dar errado. Pode faltar um fecha, como em (( , que abre duas vezes e nunca fecha. Pode sobrar um fecha, como em ()), com um fechamento sem par. E pode haver cruzamento, como em ([)], onde os pares se atravessam na ordem errada. Um bom algoritmo precisa pegar as três.

Por que a pilha é a ferramenta perfeita aqui? Porque o balanceamento tem exatamente a estrutura aninhada que a pilha adora. Quando você abre um parêntese dentro de outro, o de dentro precisa fechar antes do de fora, na ordem inversa da abertura, que é a regra LIFO. O último que você abriu é o primeiro que deve fechar. Guardar os abre numa pilha e conferir cada fecha contra o topo reproduz essa lógica de aninhamento de forma direta. É um daqueles casamentos entre problema e estrutura que, uma vez que você enxerga, nunca mais esquece.

A expressão ( [ ] ) sendo processada da esquerda para a direita, com o estado da pilha em cada passo. Ao ler abre parêntese, ele é empilhado; ao ler abre colchete, ele vai para o topo; ao ler fecha colchete, o colchete do topo é desempilhado; ao ler fecha parêntese, o parêntese é desempilhado e a pilha fica vazia, indicando expressão balanceada.
Cada abertura empilha; cada fechamento desempilha o par do topo. Pilha vazia no fim significa balanceada.

O algoritmo, passo a passo

O algoritmo é curto e cabe na cabeça. Percorra a expressão símbolo por símbolo. Se o símbolo é uma abertura, empilhe. Se é um fechamento, você precisa de um abre correspondente esperando no topo. Primeiro cheque se a pilha não está vazia, porque um fecha sem nada na pilha significa fechamento sobrando. Depois desempilhe e confira se o abre que saiu é do mesmo tipo do fecha atual, para pegar cruzamentos como ([)]. Ao terminar de percorrer tudo, a pilha precisa estar vazia. Se sobrou algum abre lá dentro, é porque faltou fechar. Só quando a expressão acaba com a pilha vazia é que ela está balanceada.

FUNÇÃO balanceada(expressao)
  pilha <- []
  PARA cada simbolo em expressao FAÇA
    SE simbolo é abertura ENTÃO
      empilhar(pilha, simbolo)
    SENÃO SE simbolo é fechamento ENTÃO
      SE vazia(pilha) ENTÃO
        RETORNE falso        // fecha sem par
      FIM
      abre <- desempilhar(pilha)
      SE não casa(abre, simbolo) ENTÃO
        RETORNE falso        // tipo errado, ex.: ( fecha com ]
      FIM
    FIM
  FIM
  RETORNE vazia(pilha)        // sobrou abre? entao faltou fechar
FIM

Empilha cada abertura; a cada fechamento, checa a pilha, desempilha e confere o tipo. No fim, a pilha tem que estar vazia.

🎮 Jogo da aula

O balanceamento que engana

Este algoritmo deveria dizer se os parênteses estão balanceados, mas aprova expressões que faltam fechar. Toque na linha do bug.

As três formas de erro que a pilha pega

Repare como uma única pilha detecta os três tipos de desbalanceamento com naturalidade. Quando falta um fecha, como em ((, a pilha termina com itens sobrando, então a checagem final de pilha vazia devolve falso. Quando sobra um fecha, como em ()), em algum momento você tenta desempilhar de uma pilha vazia, e o algoritmo já retorna falso na hora. Quando há cruzamento, como em ([)], o desempilhar entrega um abre de tipo diferente do fecha atual, e a comparação de tipos acusa o erro. Um problema com três armadilhas distintas, resolvido por uma estrutura de três operações. É esse tipo de elegância que faz valer a pena aprender estruturas de dados.

Teste rápido

No algoritmo de parênteses balanceados, o que garante que a expressão (( seja considerada desbalanceada?

Perguntas frequentes

O que significa uma expressão ter parênteses balanceados?
Significa que cada símbolo de abertura tem um fechamento correspondente, do tipo certo e na ordem certa. A expressão ([]) é balanceada; ([)] não é, porque os pares se cruzam; (( não é, porque falta fechar. Fórmulas matemáticas e código-fonte só são válidos com os símbolos bem casados.
Por que usar pilha e não um simples contador?
Um contador que soma nos abre e subtrai nos fecha funciona se houver um único tipo de símbolo. Mas com parênteses, colchetes e chaves misturados, o contador não pega cruzamentos como ([)]. A pilha guarda qual símbolo abriu, permitindo conferir se cada fecha casa com o abre certo. Por isso ela é a solução completa.
Como a pilha detecta um fechamento sobrando, como em ())?
Quando o algoritmo encontra um fecha, ele precisa desempilhar um abre correspondente. Se a pilha está vazia nesse momento, não há par para o fecha, então é um fechamento sobrando e o algoritmo retorna falso na hora. É por isso que a checagem de pilha vazia antes de desempilhar é essencial.
E se a expressão tiver letras e números, não só parênteses?
Sem problema. O algoritmo simplesmente ignora qualquer símbolo que não seja abertura nem fechamento. Ele empilha nos abre, confere nos fecha e passa reto por letras, números e espaços. Assim dá para checar o balanceamento de uma linha de código inteira, não só de símbolos isolados.
Por que a ordem inversa (LIFO) importa no balanceamento?
Porque parênteses aninhados fecham na ordem inversa da abertura: o último aberto é o primeiro a fechar. Em (a[b]c), o colchete abriu depois do parêntese e fecha antes dele. A pilha reproduz essa ordem naturalmente, já que o último item empilhado é o primeiro a sair, casando com a estrutura aninhada.
Esse algoritmo é usado em ferramentas reais?
Sim. Editores de código e interpretadores usam essa mesma ideia para avisar quando falta fechar um parêntese ou uma chave. Verificadores de fórmulas e analisadores de expressões também. É um dos exemplos mais didáticos de como uma estrutura de dados simples resolve um problema prático que aparece o tempo todo.

Fontes

Seu progresso fica salvo neste aparelho. Assinantes sincronizam entre os aparelhos.