La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

MODULO 2: Strutture dati avanzate e allocazione dinamica della memoria UD 3: Le Liste UD 4: Pile e Code UD 5: Alberi e grafi.

Presentazioni simili


Presentazione sul tema: "MODULO 2: Strutture dati avanzate e allocazione dinamica della memoria UD 3: Le Liste UD 4: Pile e Code UD 5: Alberi e grafi."— Transcript della presentazione:

1 MODULO 2: Strutture dati avanzate e allocazione dinamica della memoria UD 3: Le Liste UD 4: Pile e Code UD 5: Alberi e grafi

2 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. Lobiettivo 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 allinterno di un elaboratore.

3 UNITA DIDATTICA 4: Pile e code A cura di Tania Barbagallo Classe di Concorso: 42A Docente: Prof. D. Cantone

4 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++.

5 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 come strutture dinamiche di dati; definire i modelli di classe.

6 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.

7 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.

8 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.

9 Metodologia Lezione frontale Lezione dialogata Brainstorming Gruppi di lavoro

10 Strumenti Libro di testo Dispense fornite dal docente Lavagna luminosa Proiettore Computer

11 Spazi Aula Laboratorio di Informatica

12 Verifiche Questionari e test (strutturati e semistrutturati). Prove di laboratorio. Interventi di vario genere.

13 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 allimpegno, costanza nello studio e partecipazione.

14 Tempi Lezione: 5 ore Laboratorio: 3 ore Verifica: 2 ore Potenziamento e recupero: 2 ore

15 Cosè una struttura astratta di dati? Struttura astratta di dati Insiemi finiti di dati tra i quali esistono delle relazioni logiche. Ha la funzione di un contenitore che può essere riempito con dati di volta in volta di tipo diverso.

16 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

17 Operazioni relative alle strutture dati Accesso Ricerca Inserimento Modifica Cancellazione a un elemento (o nodo) per leggere il contenuto. di un elemento con un determinato contenuto. di un elemento senza alterare le connessioni con gli altri nodi. di un nuovo elemento. del contenuto di un elemento tramite la ricerca e laccesso al nodo.

18 Struttura astratta di dati Il processo di realizzazione delle strutture della memoria del calcolatore prende il nome di implementazione.

19 Struttura astratta di dati Statica Dinamica Quando non è posto alcun vincolo sulla dimensione della struttura. Quando la dimensione è definita nel momento di creazione della struttura e non può essere modificata.

20 Struttura astratta di dati Lineare Quando un nodo può avere al più un nodo che lo precede e al più un nodo che lo segue. Non lineare Quando un nodo può avere due o più nodi che lo precedono o lo seguono.

21 Strutture informative significative Array Tabelle Lista lineare Lista concatenata Pila Coda Grafi Alberi

22 La Pila Una pila (detta anche STACK) è una struttura dati lineare, i cui elementi possono essere inseriti o estratti da ununica estremità (LIFO). LIFO è acronimo di Last In First Out, ovvero lultimo ad entrare è il primo ad uscire.

23 Modalità dimpiego delle pile La pila è un tipo di dato astratto che trova impiego nellorganizzazione 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 desame viene lasciato temporaneamente sospeso per affrontare un sottoproblema che, a sua volta è lasciato in sospeso, per affrontare un nuovo sottoproblema e così via finché lultimo sottoproblema generato è messo in testa alla pila dei vari sottoprogrammi da risolvere.

24 Operazioni sulle Pile Le operazioni che si possono definire per una pila (stack) sono: Push: aggiunge nuovo elemento alla pila. Pop: elimina lelemento emergente dalla pila TopElem: ritorna il valore del primo elemento della 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 lelemento inserito da meno tempo!

25 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 limplementazione di una pila servono: uno spazio di memoria ordinato, dove inserire gli elementi; un indice per sapere quale è lultimo elemento inserito.

26 La pila come struttura statica Lindice 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 5 Top = 0Pila vuota Top=maxPila piena

27 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]; } … }

28 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

29 Definizione della procedura TopElem E la procedura che restituisce il valore delloggetto in cima. public int TopElem() {if (IsEmpty()) return 0); return elem[top-1] ; }

30 Definizione della procedura Push Nella procedura di inserimento bisogna eseguire i seguenti passi: verificare che la pila non sia piena; inserire lelemento appena passato; spostare di una posizione in alto lindice top. public bool Push(int val) {if (IsFull()) return false); elem[top++] = val; return true; }

31 Definizione della procedura Pop Nella procedura di estrazione bisogna eseguire i seguenti passi: verificare che la pila non sia vuota; decrementare il valore dellindice; leggere loggetto che sta in cima alla pila. public int Pop() {if (IsEmpty()) return 0); return elem[--top] ; }

32 Esercizio da proporre agli studenti Dati in input una sequenza di numeri, visualizzarla in ordine inverso. Lultimo numero della sequenza sia zero. Descrizione del problema I numeri della sequenza vengono acquisiti da tastiera uno ad uno ed inseriti nella pila con loperazione di Push, finché viene inserito il valore 0. Successivamente in una ripetizione i numeri vengono estratti dalla pila con loperazione di Pop finché la pila è vuota. Dati di input Numeri della sequenza. Dati di output Numeri in ordine inverso allinserimento.

33 Gestione statica e gestione dinamica Gestione statica Le aree di memoria richieste dal codice sorgente vengono predisposte dal compilatore attraverso la dichiarazione delle variabili e allocate allavviamento del programma eseguibile. Le istruzioni per lallocazione di nuova memoria vengono richiamate durante lesecuzione del programma. Gestione dinamica

34 C++ :istruzioni relative alla memoria New Per lallocazione di nuova memoria. Delete Per la cancellazione di unarea di memoria.

35 Istruzione: New Questa istruzione restituisce lindirizzo 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: int *p=new int;

36 Istruzione: Delete Questa istruzione permette di cancellare un indirizzo di memoria. E seguita dallindirizzo di memoria da deallocare, solitamente contenuto in un puntatore. Esempio: delete p;

37 La pila come struttura dinamica dati link dati link dati link Push Pop Si distingue una parte di dati e una parte di puntatori di collegamento (link)

38 Esempio garage Creare la classe con i relativi metodi per gestire con unorganizzazione LIFO le tessere degli abbonati di un garage di autovetture. Il numero di posti auto del garage non è conosciuto a priori.

39 Esempio garage Organizzazione LIFO con gestione dinamica della memoria Per realizzare tale struttura si deve definire lelemento della pila che contiene linformazione, cioè il numero dellabbonato. 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.

40 Esempio garage - DESCRIZIONE DEGLI OGGETTI Lista cima coda Inserisci Posto PostiOccupati Tessera numero *successiva 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.

41 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

42 Esempio garage – Codice C++ (1) #include class Tessera { public: int numero; Tessera *successiva ; }; // fine classe La classe Tessera è formata da una parte contenente il dato vero e proprio, cioè il numero dellabbonato e una parte per il collegamento con lelemento successivo della pila (*successiva).

43 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.

44 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 listruzione new per creare un nuovo elemento della lista, inserisce i dati ricevuti nellapposita area e aggiorna il puntatore *cima in modo da creare un collegamento con lultimo elemento inserito.

45 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.

46 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; } Si utilizza loverloading delloperatore >>, per acquisire da tastiera un tipo di dato booleano, indicante lingresso di un cliente o la chiusura del garage. Il metodopostiOccupati restituisce il numero di posti occupati.

47 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) <

48 Output prodotto dallesecuzione 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 PostoCliente OUTPUT INPUT da tastiera

49 Osservazioni (1) In questo caso il programma riporta lelenco 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 nellesecuzione.

50 Osservazioni (2) La gestione delle pile vista finora prevede la memorizzazione di un solo dato (numero). In una soluzione più generale si deve prevedere unopportuna struttura per la parte dedicata ai dati.

51 Osservazioni (3) typedef struct DatiTessera { int numero; char nome_cliente[30]; char targa_auto[30]; } DatiTessera; class Tessera { public: // parte dei dati DatiTessera dato; // parte dei links Tessera *successiva; // costruttore Tessera() : successiva(0) {} }; In una soluzione più generale, nellesempio dellautorimessa è possibile introdurre informazioni dati relative ai clienti prevedendo di conseguenza unopportuna struttura per la parte dedicata ai dati.

52 Esempio pila Scrivere il codice in grado di gestire una pila. Verificarne il funzionamento utilizzando un programma di collaudo in cui la struttura dei dati contenga un intero e un reale. Soluzione per la gestione di una generica pila

53 Esempio pila - DESCRIZIONE DEGLI OGGETTI Pila *cima conta Pila ~ Pila Push Pop Size Nodo dato *successivo Nodo In una gestione generica delle pile la classe della lista dispone dei seguenti metodi: Push(), che aggiunge un elemento alla pila; Pop(), che estrae lultimo elemento inserito; Size(), che restituisce il numero di elementi presenti nella lista attraverso lattributo conta. ~ Pila è il distruttore definito per leliminazione di eventuali dati rimasti in memoria.

54 Algoritmo in pseudocodifica INIZIO crea oggetto pila di tipo Pila chiedi numero intero, leggi (dato.x) MENTRE (dato.x<>0) chiedi numero reale, leggi (dato.y) inserisci dato nella pila chiedi numero intero, leggi (dato.x) chiedi svuotamento della pila, leggi (risp) SE (risp==si) MENTRE (dimensione della pila<>0) estrai dato dalla pila scrivi(dato.x, dato.y) scrivi (la memoria è stata liberata) FINE

55 Esempio pila – Codice C++ (1) //STRUTTURA DEI DATI typedef struct Dato { int x; float y; } Dato; const Dato Dato_NULLO = {0,0.0}; //PILA #include class Nodo { public: Dato dato; Nodo *successivo ; Nodo (Dato d=Dato_NULLO, Nodo *n=0): dato(d), successivo(n) {} }; // fine classe

56 Esempio pila – Codice C++ (2) class Pila { Nodo *cima; double conta public: Pila() : cima(0), conta(0) {} ~ Pila () {while (Size() ) Pop();} virtual bool Push(Dato &d) { Nodo *p = new Nodo(d, cima); if (!p) { cerr<< \nMemoria esaurita\n; return false; } cima = p; conta++; return true; }

57 Esempio pila – Codice C++ (3) virtual Dato Pop() { Nodo *p = cima; Dato d = Dato_NULLO; if (p) { d =p->dato; cima = p ->successivo; delete p; conta--; } return d; } virtua double Size() { return conta; } }; // fine classe

58 Esempio pila – Codice C++ (4) void main() { Pila pila; Dato dato = Dato_NULLO; char risposta; cout << Immissione di un intero e di un reale (0 = fine): ; cin >> dato.x; while (dato.x) { cin >> dato.y; if (!(pila.Push(dato)))return ; cout << Immissione di un intero e di un reale (0 = fine): ; cin >> dato.x; } // fine while …

59 Esempio pila – Codice C++ (5) … cout << endl; cout << Procedere allo svuotamento della pila (S/N) ? ; cin >> risposta; if risposta == S ׀ ׀ risposta == s ) { while (pila.Size() ) { dato = pila.Pop(); cout << dato.x << << dato.y << endl; } cout << La memoria è stata liberata << endl; }

60 Osservazioni (1) Dopo la struttura dei dati è stata definita la costante di annullamento del loro contenuto Dato_NULLO.Tale costante risulta molto utile per la creazione di un costruttore con valori di default: Nodo(Dato d=Dato_NULLO, Nodo *n=0): dato(d), successivo(n) {}

61 Osservazioni (2) Questo tipo di costruttore, che giustifica limpiego di una classe anziché di una struttura per la definizione degli elementi della lista, permette di inizializzare un nuovo elemento durante la sua creazione: Nodo *p = new Nodo(d, cima);

62 Osservazioni (3) Questo modo di inserire i dati nel nuovo elemento della lista risulta più elegante rispetto a quello tradizionale: N. B. Gli attributi della classe sono privati e i metodi sono tutti virtual. Nodo *p = new Nodo; … P->dato = d; P->successivo = cima;

63 La Coda Le code (queue) sono strutture lineari i cui elementi si inseriscono da un estremo e si estraggono dallaltro (FIFO). FIFO è acronimo di First In First Out, ovvero il primo entrato è il primo ad uscire.

64 Modalità dimpiego delle code Come si usa dire impilare o accatastare riferendosi alle pile, si dice accodare riferendosi alle code. Lavorando sui computer multiutente è frequente che si accodino stampe o lavori nelle rispettive code: i moduli software del sistema operativo che gestiscono queste attività del sistema di elaborazione seguono infatti il principio FIFO. Così, ad esempio, se più utenti richiedono le stampe sulla stessa stampante, esse vengono eseguite nello stesso ordine con cui sono state richieste (coda di SPOOL).

65 Operazioni sulle Code Le operazioni che si possono definire per una coda (queue) sono: Enqueue (o Push): aggiunge nuovo elemento alla coda. Dequeue (o Pop): estrae un elemento dalla coda. FirstElem: ritorna il valore del primo elemento della coda, senza estrarlo. IsEmpty: per verificare se la coda è vuota (ritorna true se la coda non ha elementi). IsFull: per verificare se la coda è piena. ClearQueue: per cancellare tutti i dati. viene ritornato lelemento inserito da più tempo!

66 La coda come struttura statica In alcuni casi anche le strutture FIFO hanno una dimensione limitata, oltre la quale non vengono più accettati inserimenti. Per definire una coda servono: uno spazio di memoria ordinato, dove inserire gli elementi; due indici per sapere quali sono il primo e lultimo elemento.

67 La coda – Estrazione\Inserimento In seguito ad ogni estrazione, gli elementi rimanenti vengono fatti avanzare di una posizione. Per linserimento, invece, viene occupata lultima posizione libera

68 La coda come struttura statica E possibile implementare una coda per mezzo di un array. Si tenga presente, però, che diventa oneroso eseguire uno shift di tutti gli elementi dopo ogni estrazione.

69 La coda come struttura statica head tail head Per tale motivo conviene pensare allarray come una struttura nella quale si passa dallultimo al primo elemento in modo circolare (nel quale lelemento che segue lultimo è il primo). E quindi occorre tener presente due indici, head e tail, che indicano il primo elemento e lultimo.

70 La coda come struttura circolare Il vantaggio di una simile struttura logica è che non è necessario effettuare uno shift per ogni inserimento, ma basta una sola assegnazione (più la modifica della variabile head). Head viene incrementato per ogni operazione di Estrazione. Tail viene incrementato per ogni operazione di Inserimento.

71 La coda come struttura circolare Il valore di tail potrà raggiungere, ma non superare il valore di head (a seguito di operazioni di Inserimento ne segue il riempimento della coda). tail head

72 La coda come struttura circolare Analogamente, il valore di head non potrà superare tail (dopo operazioni di Estrazione ne segue lo svuotamento della coda). head tail

73 La coda come struttura circolare Se però i due puntatori coincidono, dobbiamo distinguere le condizioni di coda vuota o coda con un solo elemento. Si può decidere se: lasciare sempre una casella vuota e far indicare a tail la prima posizione vuota; usare una variabile booleana per sapere se la coda contiene elementi.

74 La coda come struttura circolare Nel primo caso gli indici head e tail si possono sovrapporre solo se la coda è vuota. Head punta al primo elemento della coda. Tail punta alla prima posizione libera dopo lultimo elemento (tranne se la coda è vuota). In ogni caso rimane sempre una casella vuota. tail head x x x x xx x x x

75 La coda come struttura circolare Nel secondo caso si ha: Head punta alla prima posizione piena. Tail punta allultima posizione piena (tranne se la coda è vuota). In tal caso se gli indici head e tail si sovrappongono la coda può essere vuota o con un solo elemento. Tramite una variabile booleana si possono distinguere i due casi. head tail head Empty=trueEmpty=false x

76 La coda come struttura circolare Nella implementazione si considererà il primo caso cioè si fa in modo che rimanga sempre una casella vuota. Head punta al primo elemento della coda. Tail punta alla prima posizione libera dopo lultimo elemento. Qualunque operazione coinvolga gli indici deve essere fatta modulo la dimensione dellarray.

77 Esempio (1) A AB head tail Coda vuota head tail ABC ABCDBCD head tail Push(A) Push(B)Push(C) Push(D) Pop(A)

78 Esempio (2) BCDE BCDEF head tailhead tail head tail Coda piena GCDEFCDEF Coda piena GDEFGEF Push(G) Push(E) Push(F) Pop(B) Pop(C)Pop(D)

79 Esempio (3) GH headtailheadtail H head tail GHEFGHF Coda vuota Pop(E) Push(H) Pop(F)Pop(G) Pop(H)

80 Definizione della classe coda public class Coda { private int head, tail; private final int MAX; private int elem[]; private static final int MAXDEFAULT = 10; public Coda() {this(MAXDEFAULT); } public Coda(int max) {head = tail = 0; MAX = max; elem = new int[MAX]; } … }

81 Definizione della classe coda public class Coda { … public bool IsFull() {return (head == (tail+1) % MAX); } public bool IsEmpty() {return (head == tail); } public void ClearQueue() { head = tail = 0; } … } Procedura IsFull Procedura IsEmpty Procedura ClearQueue

82 Definizione della procedura FirstElem public int FirstElem() {if (IsEmpty()) return 0); return elem[head]; } E la procedura che restituisce il valore del primo elemento.

83 Definizione della proceduraPush public bool Push(int val) { if IsFull()) return false; elem[tail] = val; tail = ++tail % MAX; return true; } Nella procedura di inserimento bisogna eseguire i seguenti passi: verificare che la coda non sia piena; inserire lelemento appena passato; aumentare di una posizione lindice tail (modulo la dimensione dellarray).

84 Definizione della proceduraPop public int Pop() {if IsEmpty() return 0; int val = elem[headl]; head = ++head % MAX; return val; } Nella procedura di estrazione bisogna eseguire i seguenti passi: verificare che la coda non sia vuota; leggere loggetto che occupa la prima posizione; aumentare di una posizione il valore dellindice head (modulo la dimensione dellarray).

85 Esercizio da proporre agli studenti Dati in input una sequenza di numeri, si visualizzino gli ultimi dati inseriti secondo lordine di inserimento. Per segnalare la fine dellinserimento, lultimo numero della sequenza sia 0. Descrizione del problema I numeri della sequenza vengono inseriti nella coda in seguito a quelli già esistenti; se però nella coda tutti i posti sono occupati viene segnalato un messaggio di indisponibilità perché la coda è piena: in questo caso il procedimento forza unoperazione di estrazione allinizio della coda, prima di inserire il nuovo elemento. Al termine dellelaborazione (con linserimento del numero 0), svuotando la coda si ha il risultato desiderato. Dati di input Numeri della sequenza. Dati di output Gli ultimi numeri inseriti secondo lordine di inserimento.

86 La coda come struttura dinamica dati link dati link dati link Pop Push Si distingue una parte di dati e una parte di puntatori di collegamento (link)

87 Struttura dati di una coda La realizzazione di una coda generica prevede la stessa struttura dati vista per la pila, cioè una classe per la gestione della lista e una classe per la definizione degli elementi. In questo caso la lista contiene due puntatori ai suoi elementi in modo da gestire il caricamento, metodo Push(), e lestrazione, metodo Pop(), attraverso la modalità FIFO.

88 Esempio coda Scrivere il codice in grado di gestire una coda. Verificarne il funzionamento utilizzando un programma di collaudo in cui la struttura dei dati contenga un intero e un reale. Soluzione per la gestione di una generica coda

89 Esempio coda - DESCRIZIONE DEGLI OGGETTI Coda *cima *coda conta Coda ~ Coda Push Pop Size Nodo dato *successivo Nodo In una gestione generica delle code la classe della lista dispone dei seguenti metodi: Push(), che aggiunge un elemento alla coda; Pop(), che estrae lelemento inserito da più tempo; Size(), che restituisce il numero di elementi presenti nella lista attraverso lattributo conta. ~ Coda è il distruttore definito per leliminazione di eventuali dati rimasti in memoria.

90 Algoritmo in pseudocodifica INIZIO crea oggetto coda di tipo Coda chiedi numero intero, leggi (dato.x) MENTRE (dato.x<>0) chiedi numero reale, leggi (dato.y) inserisci dato nella coda chiedi numero intero, leggi (dato.x) chiedi svuotamento della pila, leggi (risp) SE (risp==si) MENTRE (dimensione della coda<>0 estrai dato dalla coda scrivi(dato.x, dato.y) scrivi (la memoria è stata liberata) FINE

91 Esempio coda – Codice C++ (1) //STRUTTURA DEI DATI typedef struct Dato { int x; float y; } Dato; const Dato Dato_NULLO = {0,0.0}; //CODA #include class Nodo { public: Dato dato; Nodo *successivo ; Nodo(Dato d=Dato_NULLO, Nodo *n=0): dato(d), successivo(n) {} }; // fine classe

92 Esempio coda – Codice C++ (2) class Coda { Nodo *cima; Nodo *coda; double conta public: Coda() : cima(0), conta(0) {} ~ Coda () {while (Size() ) Pop();} virtual bool Push(Dato &d) { Nodo *p = new Nodo(d); if (!p) { cerr<< \nMemoria esaurita\n; return false; } if (cima) coda->successivo =p; else cima=p; coda = p; conta++; return true; }

93 Esempio coda – Codice C++ (3) virtual Dato Pop() { Nodo *p = cima; Dato d = Dato_NULLO; if (p) { d =p->dato; cima = p ->successivo; delete p; conta--; } return d; } virtua double Size() { return conta; } }; // fine classe

94 Esempio coda – Codice C++ (4) void main() { Coda coda; Dato dato = Dato_NULLO; char risposta; cout << Immissione di un intero e di un reale (0 = fine): ; cin >> dato.x; while (dato.x) { cin >> dato.y; if (!(coda.Push(dato)))return ; cout << Immissione di un intero e di un reale (0 = fine): ; cin >> dato.x; } // fine while …

95 Esempio coda – Codice C++ (5) … cout << endl; cout << Procedere allo svuotamento della coda (S/N) ? ; cin >> risposta; if risposta == S ׀ ׀ risposta == s ) { while (coda.Size() ) { dato = coda.Pop(); cout << dato.x << << dato.y << endl; } cout << La memoria è stata liberata << endl; }

96 Osservazioni La gestione di una coda richiede una particolare attenzione per limplementazione per linserimento di nuovi elementi. La struttura dellelemento che è rappresentato dalla classe Nodo, il metodo di estrazione Pop() e il metodo che restituisce la dimensione della lista Size(), rimangono invece invariati.

97 Si può pensare di derivare la classe Coda dalla classe Pila class Coda : public Pila { Nodo *coda; double conta public: Coda() : Pila(), coda(0) {} virtual bool Push(Dato &d) { Nodo *p = new Nodo(d); if (!p) { cerr<< \nMemoria esaurita\n; return false; } if (cima) coda->successivo =p; else cima=p; coda = p; conta++; return true; } }; // fine classe Il distruttore della classe derivata viene omesso in quanto la lista viene svuotata dal distruttore della classe di base. La cima della pila non potrà più essere di tipo private.

98 FINE


Scaricare ppt "MODULO 2: Strutture dati avanzate e allocazione dinamica della memoria UD 3: Le Liste UD 4: Pile e Code UD 5: Alberi e grafi."

Presentazioni simili


Annunci Google