edubun
Português

Pilhas

Conferir se os parênteses de {[()()]} formam pares corretamente leva uma pilha e 8 pushes e pops, um para cada símbolo.

Último a entrar, primeiro a sair

Pense numa pilha de pratos. Você põe um prato limpo em cima e, quando precisa de um, pega o de cima. O prato que você pôs por último é o primeiro a sair. Uma pilha é uma estrutura de dados com exatamente essa regra, chamada último a entrar, primeiro a sair (LIFO). Ela oferece duas operações principais: push põe um valor no topo, e pop remove o valor do topo e o devolve. Muitas pilhas também oferecem peek, que olha o topo sem remover nada.

Nas notas do 6.006 do MIT, a pilha é um caso especial da interface de sequência: insert last(x) e delete last(). Isso já diz como construir uma. Ponha os valores num array dinâmico e trate o fim do array como o topo. Na unidade anterior, o fim era a ponta barata, então push e pop custam 1 passo cada (amortizado, por causa da cópia ocasional). O tamanho da pilha não faz diferença. Fazer pop numa pilha de 3 valores ou de 3 milhões de valores é o mesmo passo único.

const stack = [];
stack.push(4);
stack.push(8);
stack.push(5);
console.log(stack.pop());           // 5, o último empilhado
console.log(stack[stack.length - 1]); // peek: 8
console.log(stack.length);          // 2
Carregando

Arraste para girar. Role ou faça pinça para dar zoom.

Uma pilha desenhada como um monte. Push e pop só funcionam no topo. Escolha uma sequência de parênteses e aperte Verificar parênteses para ver uma pilha decidir se ela está balanceada.

Conferindo parênteses

Um uso clássico da pilha é conferir se os parênteses estão balanceados, o que todo editor de código e todo compilador faz. Leia o texto da esquerda para a direita. Cada símbolo de abertura, (, [ ou {, é empilhado. Cada símbolo de fechamento precisa combinar com o de abertura que está no topo da pilha: se combinar, desempilhe esse símbolo; se a pilha estiver vazia ou o topo for de outro tipo, a sequência não está balanceada. No fim, a pilha precisa estar vazia, senão algum símbolo aberto nunca foi fechado.

Experimente as sequências no laboratório. {[()()]} precisa de 4 pushes e 4 pops, 8 passos, e termina com a pilha vazia. ([)] falha no terceiro caractere: o ) chega enquanto [ está no topo. (() vai até o fim com um ( sobrando. Por que uma pilha serve para esse trabalho? Os parênteses se aninham, e o aberto mais recentemente precisa ser o primeiro a fechar. Isso é último a entrar, primeiro a sair.

Onde mais as pilhas aparecem

  • A pilha de chamadas. Quando a função a chama b e b chama c, o computador empilha um registro para cada chamada. Quando c retorna, o registro dela é desempilhado e b continua de onde parou. Uma recursão infinita enche essa pilha, que é o erro de "stack overflow" (estouro de pilha).
  • Desfazer. Um editor empilha cada mudança. Desfazer desempilha a mudança mais recente e a reverte.
  • Botão Voltar. Um navegador empilha cada página que você deixa; Voltar desempilha a última.
  • Busca em profundidade. O curso de algoritmos usou uma pilha para ir o mais fundo possível num labirinto antes de voltar.
ContextoA pilha como ideia de computação costuma ser atribuída a Friedrich L. Bauer e Klaus Samelson, em Munique. Trabalhando em como traduzir fórmulas aritméticas, eles guardavam as operações adiadas num depósito em que o último item colocado é o primeiro a sair, e o chamaram de Keller, porão em alemão. Eles pediram a patente do método em 1957; ela foi concedida nos Estados Unidos em 1962. Mais ou menos na mesma época, o processamento de listas de Allen Newell, Cliff Shaw e Herbert Simon, na RAND Corporation, também dependia de pilhas, porque os programas deles eram cheios de recursão.
  1. Em que ordem uma pilha devolve os valores?
    • Primeiro a entrar, primeiro a sair
    • Último a entrar, primeiro a sair
    • O menor primeiro
    • Ordem aleatória
  2. Comece vazia. Push 4, push 8, push 5, pop, push 2. O que está no topo?
    • 4
    • 8
    • 5
    • 2
  3. Depois dessas operações, quantos valores há na pilha?
  4. Push A, depois B, depois C, depois pop até esvaziar. Ponha os valores desempilhados em ordem.
  5. Quantos pushes e pops no total leva conferir {[()()]} com o método dos parênteses?
  6. Conferindo ([)] a partir da esquerda, onde ele falha?
    • No primeiro (
    • No [
    • No )
    • No ] final
  7. O que há de errado com (() ?
    • Um símbolo de fechamento chega com a pilha vazia
    • Um ( ainda está na pilha no fim
    • Faltam colchetes
    • Nada; está balanceado
  8. Fazer pop numa pilha (guardada num array dinâmico) que tem 1000 valores leva quantos passos?
  9. A função main chama draw, e draw chama line. Enquanto line roda, qual registro está no topo da pilha de chamadas?
    • main
    • draw
    • line
    • nenhum
  10. Em que ano Bauer e Samelson pediram a patente do método da pilha?
    • 1946
    • 1957
    • 1962
    • 1972
Pontos-chave
  • Uma pilha é último a entrar, primeiro a sair: push no topo, pop do topo.
  • Construída no fim de um array dinâmico, push e pop custam 1 passo cada.
  • A verificação de parênteses empilha os de abertura e desempilha a cada fechamento; {[()()]} leva 8 passos.
  • A pilha de chamadas, o desfazer e o botão Voltar são pilhas.
Fontes deste curso (11)
  • MIT OpenCourseWare 6.006 Introduction to Algorithms, Spring 2020 (Demaine, Ku, Solomon)
  • lecture notes 2 Data Structures (interface vs data structure, Sequence and Set interfaces, stack = insert_last/delete_last, queue = insert_last/delete_first, array, linked list, dynamic array, amortized Θ(1) append)
  • 4 Hashing (chaining, pigeonhole collisions, chain length n/m)
  • 6 Binary Trees Part 1 (height, traversal order, O(h) operations) and 7 Binary Trees Part 2: AVL (Adelson-Velsky and Landis, 1962) at ocw.mit.edu/courses/6-006-introduction-to-algorithms-spring-2020/pages/lecture-notes
  • MDN Web Docs, Array.prototype.shift (shifts all values left by 1)
  • Array.prototype.unshift, Map (insertion order, Map vs Object, spec requires sublinear average access) and Set (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects)
  • ECMAScript 2025 Language Specification (tc39.es/ecma262)
  • 24.1 Map Objects and 24.2 Set Objects ("must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of elements")
  • Array.prototype.shift steps (Repeat, while k < len: move element k to k - 1)
  • D. E. Knuth, The Art of Computer Programming vol. 3 (2nd ed. 1998) section 6.4 History (H. P. Luhn, IBM internal memorandum January 1953, hashing with chaining; digit pairs added mod 10, 31415926 -> 4548) via gwern.net copy, and IEEE Spectrum, "Hans Peter Luhn and the Birth of the Hashing Algorithm" (2018)
  • "A brief history of the stack", SIGCIS (sigcis.org/files/A brief history.pdf: Bauer and Samelson applied for the patent in 1957, US 3,047,228 granted July 31, 1962; IPL list processing by Newell, Simon and Shaw at RAND 1956) and Wikipedia, Information Processing Language (Newell, Shaw, Simon, RAND and Carnegie Institute of Technology, about 1956).

Data de verificação: 2026-10-18