Lo stack: tipo di dato astratto e implementazione in Java

  • 767 views
Uploaded on

Una introduzione alle variabili dinamiche. Riealaborazione di un mio lavoro precedente, però scritto in java.

Una introduzione alle variabili dinamiche. Riealaborazione di un mio lavoro precedente, però scritto in java.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
767
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
4
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Strutture dati: Stack Un'introduzione (soft) alle variabili dinamiche
  • 2. Cos'è uno stack? Una struttura dati (astratta) di tipo LIFO (Last In First Out) Ovvero, I dati sono estratti in modo inverso rispetto all'ordine di inserimento Quindi esattamente come una pila di libri, o di altri oggetti Novembre 2013 2
  • 3. Struttura Lo stack è una struttura estremamente semplice Dotato di poche operazioni: inserimento di un oggetto nello stack ed estrazione di un oggetto dallo stack Opzionalmente si possono inserire altre funzionalità di supporto, per esempio per controllare se lo stack è vuoto oppure no. Novembre 2013 3
  • 4. Struttura Le operazioni di inserimento ed estrazione sono chiamate classicamente “push” e “pop”. Lo stack è una struttura informatica FONDAMENTALE. E' usato infatti per (livello macchina): chiamate a funzioni Ricorsione Risoluzione di espressioni ... Novembre 2013 4
  • 5. Schema UML Novembre 2013 5
  • 6. Possibile scheletro di implementazione abstract public class Stack {  abstract public Object pop();  abstract public void push(Object  obj);  abstract public boolean isEmpty() ; } Novembre 2013 6
  • 7. Classe... astratta? Una classe astratta è una classe che non si implementa direttamente, ma nella quale si dichiarano tutti i metodi che si vogliono implementare nella classe “vera” E' una classe che non si può utilizzare direttamente, ma deve essere implementata tramite sottoclassi. Ricorda un po' le dichiarazioni delle funzioni in C/C++ (ma non troppo) Novembre 2013 7
  • 8. E allora? Sono possibili due implementazioni Novembre 2013 8
  • 9. Implementazione statica In questo caso, occorre allocare in anticipo lo spazio da utilizzare (tipicamente un array, stimandone la dimensione) Una variabile (tipicamente chiamata “top”) punta all'elemento dell'array nel quale avverrà il prossimo inserimento. Novembre 2013 9
  • 10. Implementazione statica (1/2) public class StackStatico extends Stack{     public static final int SIZE = 100;     private int top;     private Object arr[];     StackStatico() {arr=new Object[SIZE];         top=0;};     public Object pop(){         if (isEmpty()) return null;         return arr[­­top]; };op());  } Novembre 2013 10
  • 11. Implementazione statica (2/2) public class StackStatico extends Stack{     public void push(Object obj) {         arr[top++]=obj;     }     public boolean isEmpty() {         return top==0;     }; } Novembre 2013 11
  • 12. Stack statico: programma di esempio public static void main(String args[]) {         StackStatico s=new StackStatico();         s.push(new Integer(83));         s.push(new Integer(12));         s.push(new Integer(67));         while (!s.isEmpty()) {             System.out.println(s.pop());         }     } Novembre 2013 12
  • 13. Problema Obbligo di definire le dimensioni massime → possibilità di eccedere le dimensioni stabilite (“stack overflow”) se la nostra stima è troppo bassa. → spreco di memoria, se la nostra stima è troppo alta Novembre 2013 13
  • 14. Alternativa? Si! Possiamo implementare lo stack in modo dinamico, cioè utilizzando quella parte di memoria RAM che non è utilizzata da nessun processo ed è a disposizione (tale memoria è chiamata memoria heap, o “mucchio di memoria”) Utilizzeremo così solo la memoria che ci serve (o quasi) Novembre 2013
  • 15. La struttura dell'oggetto Per farlo, dovremo utilizzare un oggetto molto diverso, formato da due attributi il campo informativo (dato) che contiene l'oggetto un puntatore la seconda è un puntatore che punta all'elemento successivo (idealmente, una “freccia”) Novembre 2013 15
  • 16. Novembre 2013 16
  • 17. La struttura public class StackDinamico { private Object obj; private StackDinamico next; public StackDinamico() {}; public Object pop(){}; public void push(Object o) {} public boolean isEmpty(){}; } Novembre 2013 17
  • 18. Inizializzazione Dovremo sempre avere modo di recuperare il primo elemento dello stack: chiameremo top la variabile che punta all'elemento in cima allo stack; Tale variabile sarà nel main (e la chiameremo s) s = new StackDinamico(); Novembre 2013 18
  • 19. Graficamente... s=new StackDinamico(); MEMORIA HEAP s t Novembre 2013 19
  • 20. Questo elemento serve solo a “segnare” la fine dello stack, e non contiene oggetti. E' gestito dal costruttore Novembre 2013 20
  • 21. Inizializzazione In sostanza, l'inizializzazione è gestita totalmente dal costruttore, che dovrà fare due cose: Settare a null il puntatore all'elemento successivo Settare a null il puntatore al dato (non ci sono dati, infatti – e in questo primo elemento non ci saranno mai.) Novembre 2013 21
  • 22. Inserimento di un elemento (PUSH) Per inserire un elemento nello stack, dobbiamo utilizzare il metodo push(). Al suo interno, dovremo creare un nuovo elemento in una variabile di appoggio, poi questo nuovo elemento diverrà il nuovo elemento “più in alto dello stack”. Dopo aver inserito l'informazione, lo agganceremo allo stack preesistente; Novembre 2013 22
  • 23. Graficamente... StackDinamico t=new StackDinamico(); MEMORIA HEAP s t Novembre 2013 23
  • 24. Graficamente... t.obj=o; // object è un Integer con valore 83 MEMORIA HEAP s t Novembre 2013 83 24
  • 25. Graficamente... t.next=s.next; MEMORIA HEAP s t Novembre 2013 83 25
  • 26. Graficamente... s.next=t; MEMORIA HEAP s t Novembre 2013 83 26
  • 27. Graficamente... Ripetiamo il codice, ma questa volta inseriamo “12” MEMORIA HEAP s t Novembre 2013 83 27
  • 28. Graficamente... t=new StackDinamico(); MEMORIA HEAP s t Novembre 2013 83 28
  • 29. Graficamente... t.o=object;//object è un Integer con valore 12 MEMORIA HEAP s t 83 12 Novembre 2013 29
  • 30. Graficamente... t.next=s.next; MEMORIA HEAP s t 83 12 Novembre 2013 30
  • 31. Graficamente... s.next=t; MEMORIA HEAP s t 83 12 Novembre 2013 31
  • 32. Eliminazione di un elemento (POP) Come funziona il metodo pop()? Ancora più semplice. Stacchiamo il primo elemento (se esiste) dal resto dello stack, assegnandolo alla variabile t “Andiamo avanti” di un posto Restituiamo l'oggetto contenuto Poniamo t=null (opzionale). Privo di riferimenti, la memoria allocata torna disponibile. (In C/C++ va deallocata manualmente) Novembre 2013 32
  • 33. Graficamente... MEMORIA HEAP s t 83 12 Novembre 2013 33
  • 34. Graficamente... if (s.next==null) return null; MEMORIA HEAP s t 83 12 Novembre 2013 34
  • 35. Graficamente... t=s; MEMORIA HEAP s t 83 12 Novembre 2013 35
  • 36. Graficamente... s=s.next; MEMORIA HEAP s t 83 12 Novembre 2013 36
  • 37. Importante! L'assegnazione di puntatori significa: “puntano allo MEMORIA HEAP stesso oggetto” s t 83 12 Novembre 2013 37
  • 38. Importante! return t.o;//restituisce l'oggetto MEMORIA HEAP s t 83 out 12 Novembre 2013 38
  • 39. Importante! Al termine del metodo, la variabile t scompare MEMORIA HEAP s t 83 12 Novembre 2013 39
  • 40. Importante! Al termine del metodo, la variabile t scompare MEMORIA HEAP s t 83 12 Novembre 2013 40
  • 41. Importante! Priva di riferimenti, la memoria torna nell'heap MEMORIA HEAP s 83 Novembre 2013 41
  • 42. Confronto tra le due implementazioni Novembre 2013 42
  • 43. Migliorabile? Certamente si... Non permette di “osservare” il dato nello stack senza toglierlo Non sappiamo quanti elementi contiene Altri miglioramenti, al vostro buon cuore Novembre 2013 43
  • 44. Migliorabile? Realizzate quindi un programma che inserisca diversi oggetti nello stack e li estragga. Implementate ENTRAMBE le versioni (statiche e dinamiche) dello stack, con la stessa interfaccia pubblica. Il programma di prova deve funzionare in modo identico con le due implementazioni. Novembre 2013 44
  • 45. BUON LAVORO Novembre 2013 45