Sei sulla pagina 1di 10

Tipi di Dato Astratti

Stack

Prof. Giuseppe Riccardi


Dipartimento Ingegneria e Scienza delle Informazioni
Università degli Studi di Trento

Indice

• Stack
• Operazioni sullo Stack

1
Stack
•  Stack
†  Anche chiamata Lista LIFO, PushDown List
•  Modello matematico
†  È lista L dove inserimento ed estrazione degli elementi
avviene esclusivamente da un solo lato, top.
†  Esempio: pila di libri, piatti etc..

Pila - Operazioni
•  Inserisci elemento nella pila S
†  Push(S, Elemento)
•  Estrai elemento dalla pila S
†  Pop(S)
•  Restituisci testa della pila S
†  Top(S)
•  Controlla se Stack vuoto
†  StackIsEmpty(S)
•  Controlla se Stack pieno
†  StackIsFull(S)

2
Esempio

push(7)
push(1) 7 pop
push(4) 1 7 7 pop
push(2) 4 1 1 1 1 pop
2 4 4 4 4 4 4
2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3 3

Esempio
Notazione Infissaà Postfissa

•  Notazione infissa, espressioni si valutano a


partire dalle espressione elementari contenute
tra parentesi e/o seguendo tabelle di priorità/
associatività
(5+3)à8

3
Cont.
•  Nella notazione postfissa:
5 3 + à8
1.  Si valuta da sinistra a destra stringa input ( operandi e
operatori)
2.  Si accumulano sullo stack simboli fino a che non si
incontra operatore che si applica ai due operandi in cima
allo stack.
3.  Risultato si scrive in cima allo stack
4.  Si procede fino a ultimo simbolo input
Il risultato è il valore dell’unico elemento rimasto nello stack

Cont.
•  Nella notazione postfissa:
5 3 + à8

Pop
Pop 3+5
Push(3)
Push(5) Push(8)
3
5 5 8

4
Conversione da Infissa a Postfissa
•  Infissa: (5 * (((9 + 8) * (4 * 6)) +7))‫‏‬
•  Postfissa: 5 9 8 + 4 6 * * 7 + *

Conversione da Infissa a Postfissa


•  Procediamo da sinistra a destra nell’espressione:
•  Se troviamo un numero lo scriviamo in output.
•  Se incontriamo una parentesi aperta o uno
spazio li ignoriamo;
•  Se incontriamo un operatore lo inseriamo nello
stack;
•  Se incontriamo una parentesi chiusa estraiamo
l’elemento che sta in cima allo stack e lo
stampiamo in output.

5
Conversione infissa ⇒ postfissa
( 9 + ( 8 * 4 ) )
output Stack
( 9 + ( 8 * 4 ‫)‏ )‏‬
( 9 + ( 8 * 4 ‫)‏ )‏‬ 9
( 9 + ( 8 * 4 ‫)‏ )‏‬ 9 +
( 9 + ( 8 * 4 ‫)‏ )‏‬ 9 +
( 9 + ( 8 * 4 ‫)‏ )‏‬ 98 +
( 9 + ( 8 * 4 ‫)‏ )‏‬ 98 * +
( 9 + ( 8 * 4 ‫)‏ )‏‬ 984 *+
( 9 + ( 8 * 4 ‫)‏ )‏‬ 984* +
( 9 + ( 8 * 4 ‫)‏ )‏‬ 984*+

Conversione infissa ⇒ postfissa


void infissa2postfissa(const char * e) {
/*Alloca stack S */
…..
int i = 0;
for (i = 0; e[i] != ‘\0’; i++) {
if ((e[i] == ‘(‘) || (e[i] == ‘ ‘)) continue;
if (e[i] == ‘)’)
printf(“%c “, Pop(S));
if ((e[i] == ‘+’) || (e[i] == ‘*’) ||
(e[i] == ‘-’) || (e[i] == ‘/’))‫‏‬
Push(S, e[i]);
if ((e[i] >= ‘0’) && (e[i] <= ‘9’))
printf(“%c “, e[i]);
}
printf(“\n”);
/*Free S*/ La conversione considera solo
} numeri compresi tra 0 e 9.

6
Esercizio
•  Modificare la funzione precedente in modo che gestisca
numeri di 2, 3,..n cifre.

Esercizio
•  Scrivere una funzione che prende in input una
espressione postfissa e la valuti.

Output Stack
9 8 4 * + 9
9 8 4 * + 8 9
9 8 4 * + 4 8 9
9 8 4 * + 32 9
9 8 4 * + 41
9 8 4 * + 41

7
Implementazione dello Stack

•  Esistono due soluzioni alternative per


implementare un ADT di tipo stack.
•  La prima basata su array
•  Occupazione di memoria fissa.
•  Dimensione massima fissa.
•  La seconda basata su liste
•  Occupazione di memoria variabile, dipende da quanti
elementi sono inseriti.
•  Dimensione massima può crescere dinamicamente.

Implementazione Stack: Array


int

Numero elementi
presenti nello stack
struct TipoStack {
int N; Numero massimo di
elementi memorizzabili
int dim; nello stack

int *s;
}; Array per memorizzare gli
elementi.

8
Tipo di Dato Astratto Stack

// Definizione dell’ADT stack di Elem


// (implementazione non specificata)
typedef struct TipoStack Stack;
typedef struct TipoStack *StackPtr;

// Verifica se lo stack è vuoto o no


boolean StackIsEmpty(StackPtr p);

// Inserisce l’elemento intero d nello stack


// incrementando la dimensione dello stack
void Push(StackPtr p, TipoElemento Elem);

// Rimuove un elemento dallo stack,


// riducendo la dimensione dello stack e ritorna il
valore
int Pop(StackPtr p);

struct TipoStack
{
Implementazione Stack: Array int N;
bool StackIsEmpty(StackPtr p) {
int dim;
return (p->N == 0); int *s;
} };
bool StackIsFull(StackPtr p) {
return (p->N == p->dim);
}

void Push(StackPtr p, int x) {


if (StackIsFull())
error(“Attempting to add an elemento to a full stack”);
p->s[p->N] = x;
p->N = p->N + 1;
}
int Pop(StackPtr p) {
if (StackIsEmpty(p))
error(“Attempting to remove an elelement from an empty stack”);
p->N = p->N - 1;
return p->s[p->N];
}

9
Caratteristiche delle operazioni Push e Pop

•  Le operazioni di push usano tempo costante sia nel


caso di implementazione con array che con liste
concatenate.
•  Le operazioni di pop usano tempo costante sia nel caso
di implementazione con array che con liste
concatenate.

10

Potrebbero piacerti anche