Stack e code sono insiemi dinamici in cui l’elemento rimosso dall’insieme con l’operazione di cancellazione è sempre predeterminato.
In uno stack, l’elemento cancellato è quello più recentemente inserito. Gli stack rispettano la politica LIFO (last-in, first-out).
In una coda, l’elemento cancellato è sempre quello che è rimasto più a lungo nell’insieme. Le code rispettano la politica FIFO (first-in, first out)
In uno stack un nuovo elemento è sempre posto in testa agli altri, mentre nella coda esso è posto dopo tutti gli altri.
Ci sono molti modi per implementare stack e code su un computer. Cominciamo con una implementazione di stack utilizzando array.
Le operazioni fondamentali su Stack sono:
Un esempio di stack può essere dato da una pila di piatti posta su un tavolo.
Si noti che l’ordine in cui i piatti sono tolti dallo stack è inversa all’ordine in cui essi sono stati inseriti nello stack, visto che solo il top dello stack è accessibile.
Un’altra operazione importante sugli stack è Empty-Stack, necessaria per controllare se uno stack è vuoto.
Per implementare uno stack di n elementi, si può utilizzare un array S di dimensione n.
L’array S utilizzerà l’attributo TOP che indicherà l’indice dell’elemento più recente immesso nello stack. In una implementazione si potrebbe pensare di memorizzare questo indice nel primo elemento dell’array che dunque avrà come dimensione non più n ma n+1.
Esempio (vedi figura)
Un’operazione di Pop sullo stack dell’esempio precedente, restituirà l’elemento 1 e il TOP diventerà 3.
Quando TOP=0, lo stack è vuoto, cioè non contiene elementi.
Utilizzando un array S[MAX+1] per l’implementazione di uno stack, nel modo descritto precedentemente, le operazioni di Push e Pop possono essere realizzate semplicemente nel modo indicato.
Utilizzando un array S[MAX+1] per l’implementazione di uno stack di MAX elementi, empty_stack può essere realizzata controllando se Top=0. Inoltre, si può utilizzare una procedura full_stack per controllare se lo stack è pieno, cioè se Top=MAX.
Facoltativo: Utilizzando empty_stack e full_stack è possibile realizzare una versione più efficiente di Pop e Push con controllo di errore, nel modo indicato.
La seguente procedura permette di costruire uno stack S di taglia num_elementi, sapendo che S può contenere al più MAX valori.
Cosa succede se si inserisce 0 per num_elementi?
Il seguente programma gestisce uno stack S di MAX valori. Si noti come i controlli siano indipendenti da MAX. Questo è utile quando MAX e S[MAX+1] sono dati esternamente al programma (come solitamente avviene).
void togli_da_Stack(int S[], int el)
che elimini dallo stack S tutti gli elementi uguali ad el lasciando invariato l’ordine degli altri elementi.
A differenza dello stack, una coda usa due attributi:
In pratica, usando come esempio di coda una fila ad uno sportello. L’inizio della coda è rappresentato dalla prima persona della fila (quella la prossima ad essere servita), mentre la fine della coda è rappresentata dall’ultima persona che si è aggiunta alla coda (cioè, l’ultima persona tra quelle attualmente in fila ad essere servita)
Un inserimento nella coda sarà fatto sempre alla sua fine mentre una cancellazione alla sua testa
Come per gli stack, anche per le code possiamo avere diversi modi di rappresentazione su un computer.
Iniziamo con l’utilizzo di array.
Per memorizzare una coda con massimo n elementi, possiamo utilizzare uno stack di dimensione n più due variabili che memorizzano costantemente l’indice della testa e della coda.
Come per gli stack, si può anche scegliere di memorizzare l’indice della testa e della coda nel vettore stesso.
Esempio (vedi figura)
Usando l’array Q precedente per l’implementazione di una coda, le operazioni di Cancellazione (Dequeue) e Inserimento (Enqueue) possono essere realizzate come segue:
Per la stampa di una coda, non possiamo usare esattamente la stessa procedura vista per gli stack. Infatti questa produrrebbe una inversione della coda. Per risolvere questo problema, provvediamo a invertire ulteriormente la coda.
La seguente procedura permette di costruire una coda Q di taglia num_elementi, sapendo che Q può contenere al più MAX valori
void new_queue(int Q[])
Il seguente programma gestisce una coda Q di MAX valori. Si noti come i controlli siano indipendenti da MAX. Questo è utile per le stesse motivazioni date per gli stack
void togli_dispari(int Q[])
che elimini dalla coda tutti i numeri dispari, lasciando invariato l’ordine degli elementi.
1. Introduzione al Corso - Il Linguaggio C (I parte)
2. Linguaggio C – Seconda Parte
3. Ordinamento, Ricorsione e Code di Priorità
4. Esercitazione su Ricorsione e Code di Priorità
5. Stack e Code
6. Esercitazione di Laboratorio su Stack e Code
7. Implementazioni di Liste puntate
8. Esercitazione di laboratorio su Liste Puntate Semplici
9. Implementazioni di Liste Doppiamente Puntate e Circolari
10. Esercitazione di laboratorio su Liste Doppiamente puntate
12. Esercitazione di laboratorio su Alberi Binari di Ricerca
13. Alberi Binari di Ricerca. Cancellazione di un nodo
14. Esercizio di Laboratorio. Gioco su alberi
15. Grafi: Implementazione ed operazioni di base
16. Esercitazione di laboratorio: Implementazione operazioni di bas...
17. Grafi: Inserimento e Cancellazione di un nodo. Visite in ampiez...
18. Esercitazione di laboratorio: Problema del venditore Prima part...
19. Componenti fortemente connesse e alberi minimi di copertura
20. Esercitazione di laboratorio: Problema del venditore Seconda pa...