Pile
Controllare che le parentesi in {[()()]} si accoppino correttamente richiede una pila e 8 push e pop, uno per ogni parentesi.
L'ultimo entrato è il primo a uscire
Pensa a una pila di piatti. Metti un piatto pulito in cima e, quando te ne serve uno, lo prendi dalla cima. Il piatto aggiunto per ultimo è il primo a uscire. Una pila (stack) è una struttura dati con esattamente questa regola, detta last in, first out (LIFO): l'ultimo entrato è il primo a uscire. Offre due operazioni principali: push mette un valore in cima, e pop toglie il valore in cima e lo restituisce. Molte pile offrono anche peek, che guarda la cima senza toglierla.
Negli appunti del corso 6.006 del MIT la pila è un caso particolare dell'interfaccia di sequenza: insert last(x) e delete last(). Questo dice già come costruirne una. Metti i valori in un array dinamico e tratta la fine dell'array come la cima. Nell'unità precedente la fine era l'estremità economica, quindi push e pop costano 1 passo ciascuno (ammortizzato, per via della copia occasionale). La dimensione della pila non conta. Fare pop da una pila di 3 valori o di 3 milioni di valori è lo stesso singolo passo.
const stack = [];
stack.push(4);
stack.push(8);
stack.push(5);
console.log(stack.pop()); // 5, l'ultimo inserito
console.log(stack[stack.length - 1]); // peek: 8
console.log(stack.length); // 2Trascina per ruotare. Scorri o avvicina le dita per lo zoom.
Controllare le parentesi
Un uso classico della pila è controllare che le parentesi siano bilanciate, cosa che fanno tutti gli editor di codice e i compilatori. Leggi il testo da sinistra a destra. Ogni parentesi aperta, (, [ o {, viene inserita con push. Ogni parentesi chiusa deve corrispondere a quella aperta in cima alla pila: se corrisponde, togli quella aperta con pop; se la pila è vuota o in cima c'è un tipo diverso, la stringa non è bilanciata. Alla fine la pila deve essere vuota, altrimenti qualche parentesi aperta non è mai stata chiusa.
Prova le stringhe nel laboratorio. {[()()]} richiede 4 push e 4 pop, 8 passi, e finisce con la pila vuota. ([)] fallisce al terzo carattere: la ) arriva mentre in cima c'è [. (() arriva alla fine con una ( avanzata. Perché una pila è adatta a questo lavoro? Le parentesi si annidano, e quella aperta più di recente deve essere la prima a chiudersi. È proprio «l'ultimo entrato è il primo a uscire».
Dove compaiono ancora le pile
- La pila delle chiamate. Quando la funzione a chiama b e b chiama c, il computer fa il push di un record per ogni chiamata. Quando c termina, il suo record viene tolto con pop e b continua da dove si era fermata. Una ricorsione infinita riempie questa pila: è l'errore di «stack overflow».
- Annulla. Un editor fa il push di ogni modifica. Annulla fa il pop della modifica più recente e la ribalta.
- Pulsante Indietro. Un browser fa il push di ogni pagina che lasci; Indietro fa il pop dell'ultima.
- Visita in profondità. Il corso di algoritmi usava una pila per andare il più a fondo possibile in un labirinto prima di tornare indietro.
- In che ordine una pila restituisce i valori?
- Il primo entrato è il primo a uscire
- L'ultimo entrato è il primo a uscire
- Prima il più piccolo
- In ordine casuale
- Parti da vuota. Push 4, push 8, push 5, pop, push 2. Che cosa c'è in cima?
- 4
- 8
- 5
- 2
- Dopo queste operazioni, quanti valori ci sono sulla pila?
- Push di A, poi di B, poi di C, poi pop fino a svuotarla. Metti in ordine i valori tolti.
- Quanti push e pop in tutto richiede il controllo di {[()()]} con il metodo delle parentesi?
- Controllando ([)] da sinistra, dove fallisce?
- Alla prima (
- Alla [
- Alla )
- All'ultima ]
- Che cosa non va in (() ?
- Una parentesi chiusa arriva su una pila vuota
- Alla fine c'è ancora una ( sulla pila
- Mancano le parentesi quadre
- Niente: è bilanciata
- Fare pop da una pila (memorizzata in un array dinamico) che contiene 1000 valori richiede quanti passi?
- La funzione main chiama draw, e draw chiama line. Mentre line è in esecuzione, quale record sta in cima alla pila delle chiamate?
- main
- draw
- line
- nessuno
- In che anno Bauer e Samelson chiesero il brevetto sul metodo della pila?
- 1946
- 1957
- 1962
- 1972
- Una pila segue la regola «l'ultimo entrato è il primo a uscire»: push in cima, pop dalla cima.
- Costruiti sulla fine di un array dinamico, push e pop costano 1 passo ciascuno.
- Il controllo delle parentesi fa push delle aperte e pop a ogni chiusa; {[()()]} richiede 8 passi.
- La pila delle chiamate, Annulla e il pulsante Indietro sono pile.
Fonti di questo corso (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).
Consultato il: 2026-10-18