1.22k likes | 1.65k Views
MODULO 2: “Strutture dati avanzate e allocazione dinamica della memoria”. UD 3: “Le Liste” UD 4: “Pile e Code” UD 5: “Alberi e grafi”. MODULO 2: “Strutture dati avanzate e allocazione dinamica della memoria”.
E N D
MODULO 2: “Strutture dati avanzate e allocazione dinamica della memoria” UD 3: “Le Liste” UD 4: “Pile e Code” UD 5: “Alberi e grafi”
MODULO 2:“Strutture dati avanzate e allocazione dinamica della memoria” Questo modulo è proposto per una quarta classe di un Istituto Tecnico Industriale ad indirizzo Informatico. L’obiettivo del modulo è di presentare: • schemi significativi di organizzazione delle informazioni; • le regole operative per la manipolazione delle strutture astratte di dati; • i metodi di rappresentazione (memorizzazione) delle strutture dati all’interno di un elaboratore.
UNITA’ DIDATTICA 4:Pile e code A cura di Tania Barbagallo Docente: Prof. D. Cantone Classe di Concorso: 42A
Prerequisiti • Conoscenza della rappresentazione della memoria di un calcolatore. • Conoscenze sicure del linguaggio C++. • Conoscenza e utilizzo delle strutture di controllo, delle strutture di dati e delle funzioni. • Conoscenza dei puntatori. • Definizione delle classi con attributi e metodi. • Applicazione dei concetti della programmazione ad oggetti nel linguaggio C++.
Competenze Al termine di questa unità didattica lo studente dovrà essere in grado di: • definire le caratteristiche delle strutture astratte ”pila” e “coda”; • comprendere la differenza tra gestione statica e gestione dinamica della memoria; • implementare”pila” e “coda” comestrutture dinamiche di dati; • definire i modelli di classe.
Conoscenze Al termine di questa unità didattica lo studente dovrà possedere le seguenti conoscenze: • strutture astratte di “pila” e “coda”; • creazione dinamica di aree di memoria; • gestione di pile e code; • modelli di classe.
Abilità Al termine di questa unità didattica lo studente dovrà aver acquisito le seguenti abilità: • saper utilizzare i metodi per la gestione della ”pila” ; • saper utilizzare i metodi per la gestione della “coda”.
Contenuti • Richiami sul concetto di struttura astratta di dati. • La ”pila” come struttura statica. • La ”pila” come struttura dinamica. • La “coda” come struttura statica. • La “coda” come struttura dinamica.
Metodologia • Lezione frontale • Lezione dialogata • Brainstorming • Gruppi di lavoro
Strumenti • Libro di testo • Dispense fornite dal docente • Lavagna luminosa • Proiettore • Computer
Spazi • Aula • Laboratorio di Informatica
Verifiche • Questionari e test (strutturati e semistrutturati). • Prove di laboratorio. • Interventi di vario genere.
Valutazione • Di tipo sommativo - in relazione al raggiungimento degli obiettivi; sia in termini di conoscenza dei contenuti, sia in termini di acquisizione di competenze e abilità specifiche. • Di tipo formativo - in relazione all’impegno, costanza nello studio e partecipazione.
Tempi • Lezione: 5 ore • Laboratorio: 3 ore • Verifica: 2ore • Potenziamento e recupero: 2 ore
Esempi di insiemi di dati correlati tra loro da relazioni logiche • Elenco telefonico • Schedario di una biblioteca • Elenco degli alunni di una classe • Le tessere degli abbonati di un garage di autovetture
Operazioni relative alle strutture dati a un elemento (o nodo) per leggere il contenuto. Accesso di un elemento con un determinato contenuto. Ricerca Inserimento di un nuovo elemento. del contenuto di un elemento tramite la ricerca e l’accesso al nodo. Modifica di un elemento senza alterare le connessioni con gli altri nodi. Cancellazione
Struttura astratta di dati • Il processo di realizzazione delle strutture della memoria del calcolatore prende il nome di implementazione.
Strutture informative significative • Array • Tabelle • Lista lineare • Lista concatenata • Pila • Coda • Grafi • Alberi
La Pila • Una pila (detta anche STACK)è una struttura dati lineare, i cui elementi possono essere inseriti o estratti da un’unica estremità (LIFO). LIFOè acronimo di Last In First Out, ovvero l’ultimo ad entrare è il primo ad uscire.
Modalità d’impiego delle pile • La pila è un tipo di dato astratto che trova impiego nell’organizzazione dei dati in memoria centrale in molti sistemi operativi, nonché nella memorizzazione degli indirizzi di ritorno delle funzioni. • Tale struttura è comune nei processi nei quali un problema in corso d’esame viene lasciato temporaneamente sospeso per affrontare un sottoproblema che, a sua volta è lasciato in sospeso, per affrontare un nuovo sottoproblema e così via finché l’ultimo sottoproblema generato è messo in testa alla pila dei vari sottoprogrammi da risolvere.
Operazioni sulle Pile Le operazioni che si possono definire per unapila (stack) sono: • Push:aggiunge nuovo elementoalla pila. • Pop: elimina l’elemento emergente dalla pila • TopElem:ritorna il valore del primo elementodella pila, senza estrarlo. • IsEmpty:per verificare se la pila è vuota(ritorna true se la pila non ha elementi). • IsFull:per verificare se la pila è piena. • Clear:per cancellare tutti i dati. viene ritornato l’elemento inserito da meno tempo!
La pila come struttura statica • In alcuni casi le strutture LIFO hanno una dimensione limitata, per cui è necessario definire un valore massimo di elementi inseribili. • Per l’implementazione di una pila servono: • uno spazio di memoria ordinato, dove inserire gli elementi; • un indice per sapere quale è l’ultimo elemento inserito.
La pila come struttura statica • L’indice deve tener conto di quanti elementi ci sono nella pila. • Si utilizza un array per memorizzare gli elementi e un numero intero che indica la prima posizione libera dello stack. Top = 0 Pila vuota 5 4 Top=max Pila piena 3 top 2 5 1
Definizione della classe “pila” public class Pila { private int top; private final int MAX; private int elem[]; private static final int MAXDEFAULT = 10; public Pila() { this(MAXDEFAULT); } public Pila(int max) { top = 0; MAX = max; elem = new int[MAX]; } … }
Definizione della classe “pila” public class Pila { … public bool IsFull() { return (top == MAX); } public bool IsEmpty() { return (top == 0); } public void Clear() { top = 0; } … } Procedura IsFull Procedura IsEmpty Procedura Clear
Definizione della procedura “TopElem” E’ la procedura che restituisce il valore dell’oggetto in cima. public int TopElem() { if (IsEmpty()) return 0); return elem[top-1] ; }
Definizione della procedura “Push” Nella procedura di inserimento bisogna eseguire i seguenti passi: • verificare che la pila non sia piena; • inserire l’elemento appena passato; • spostare di una posizione in alto l’indice top. public bool Push(int val) { if (IsFull()) return false); elem[top++] = val; return true; }
Definizione della procedura “Pop” Nella procedura di estrazione bisogna eseguire i seguenti passi: • verificare che la pila non sia vuota; • decrementare il valore dell’indice; • leggere l’oggetto che sta in cima alla pila. public int Pop() { if (IsEmpty()) return 0); return elem[--top] ; }
Esercizio da proporre agli studenti • Dati in input una sequenza di numeri, visualizzarla in ordine inverso. L’ultimo numero della sequenza sia zero.
Istruzione: New • Questa istruzione restituisce l’indirizzo di memoria. • Deve essere seguita dal tipo di dato a cui si vuole allocare la memoria. • Si assegna il risultato di questa istruzione a un puntatore. • Una volta esaurito lo spazio di memoria, new restituisce un puntatore vuoto (0). Esempio:
Istruzione: Delete • Questa istruzione permette di cancellare un indirizzo di memoria. • E’ seguita dall’indirizzo di memoria da deallocare, solitamente contenuto in un puntatore. Esempio:
La pila come struttura dinamica Push Pop 3 2 Si distingue una parte di datie una parte di puntatori di collegamento (link). 1
Esempio “garage” Creare la classe con i relativi metodi per gestire con un’organizzazione LIFO le tessere degli abbonati di un garage di autovetture. Il numero di posti auto del garage non è conosciuto a priori.
Esempio “garage”Organizzazione LIFO con gestione dinamica della memoria • Per realizzare tale struttura si deve definire l’elemento della pila che contiene l’informazione, cioè il numero dell’abbonato. • Quindi si predispongono le operazioni indispensabili a garantire la connessione di questi dati tra loro. • La parte di collegamento deve consentire di unire tra loro gli elementi della pila in modo da definire una sequenza ordinata per i dati memorizzati, per poter passare da un dato al successivo. • Il programma deve contenere una procedura di eliminazione delle aree create dinamicamente in modo da renderle disponibili ad altre applicazioni.
Esempio “garage”-DESCRIZIONE DEGLI OGGETTI La classe “Lista” serve per la definizione dei dati da archiviare. I suoi attributi sono i puntatori agli elementi della lista. Un elemento della lista è di tipo “Tessera” ed è formato da: numero, che rappresenta la parte dati; successiva, che costituisce la parte dei link.
Algoritmo in pseudocodifica INIZIO crea oggetto garage di tipo Pila aperto true MENTRE (aperto = true) chiedi “Numero di tessera”, leggi (num_tessera) inserisci num_tessera nella pila chiedi “0=Chiuso, 1=Ingresso cliente”, leggi (aperto) PER (i=0; i < numero posti occupati; i++) scrivi (numero posto, numero cliente) FINE
Esempio “garage” – Codice C++ (1) La classe “Tessera” è formata da una parte contenente il dato vero e proprio, cioè il numero dell’abbonato e una parte per il collegamento con l’elemento successivo della pila (*successiva) . #include <iostream.h> class Tessera { public: int numero; Tessera *successiva ; }; // fine classe
Esempio “garage” – Codice C++ (2) class Lista { Tessera *cima; public: Lista() : cima(0) {} // costruttore ~Lista () { // distruttore Tessera *tessera = cima; while (tessera) { cima = tessera ->successiva; delete tessera; tessera = cima; } } Il costruttore della classe si preoccupa di inizializzare gli attributi. Il distruttore libera la memoria svuotando la lista.
Esempio “garage” – Codice C++ (3) void Inserisci (int n) { Tessera *tessera = new Tessera; tessera ->numero = n; tessera ->successiva = cima; cima = tessera; } La funzione Inserisci serve alla creazione di ciascun elemento della pila. Il metodo Inserisci utilizza l’istruzione new per creare un nuovo elemento della lista, inserisce i dati ricevuti nell’apposita area e aggiorna il puntatore *cima in modo da creare un collegamento con l’ultimo elemento inserito.
Esempio “garage” – Codice C++ (4) int posto (int n) { int i; Tessera *tessera = cima; for (i=0; tessera!=0; i++) { if (i==n) return tessera->numero; tessera = tessera->successiva; } return –1; } Il metodo “posto” restituisce il numero di tessera del cliente che ha parcheggiato al posto n-esimo.
Esempio “garage” – Codice C++ (5) int postiOccupati () { int i; Tessera *tessera = cima; for (i=0; tessera != 0; i++) tessera = tessera->successiva; return i; } }; // fine classe istream &operator>>(istream &s, bool &b) { int r; s>>r; if (r) b = true; else b = false; retun s; } Il metodo “postiOccupati” restituisce il numero di posti occupati. Si utilizza l’overloading dell’’operatore>>, per acquisire da tastiera un tipo di dato booleano, indicante l’ingresso di un cliente o la chiusura del garage.
Esempio “garage” – Codice C++ (6) void main() { bool aperto=true; int num_tessera,i; Lista garage; while (aperto) { cout << “Numero di tessera del cliente: “; cin >> num_tessera; garage.inserisci (num_tessera); cout << “Immettere: 0= Chiuso, 1= Ingresso cliente\n“; cin >> aperto; } cout << “Posto n.\tcliente\n”; for (i=0; i < garage.postiOccupati(); i++) if (garage.posto(i) ! = -1) cout << “ “ << i << “\t\t “ garage.posto(i) <<endl; }
Output prodotto dall’esecuzione del programma • Numero di tessera del cliente: 10 Immettere 0=Chiuso, 1=Ingresso cliente 1 • Numero di tessera del cliente: 20 Immettere 0=Chiuso, 1=Ingresso cliente 1 • Numero di tessera del cliente: 30 Immettere 0=Chiuso, 1=Ingresso cliente 0 INPUT da tastiera OUTPUT
Osservazioni (1) In questo caso il programma riporta l’elenco dei clienti che occupano il garage in ordine inverso rispetto al loro ingresso in autorimessa. Da notare che il programma è in grado di gestire pile di qualsiasi dimensione limitatamente alla capacità della memoria del calcolatore impiegato nell’esecuzione.
Osservazioni (2) • La gestione delle pile vista finora prevede la memorizzazione di un solo dato (numero). In una soluzione più generale si deve prevedere un’opportuna struttura per la parte dedicata ai dati.