Fondamenti di Informatica II Ingegneria Informatica / Automatica (A-I) Meccanica Prof. M.T. PAZIENZA a.a. 2002-2003 – 3° ciclo.

Slides:



Advertisements
Presentazioni simili
Puntatori Linguaggio C.
Advertisements

1 La Standard Template Library vettori, liste, mappe, …. find, replace, reverse, sort, …. puntatori intelligenti La libreria standard STL e una libreria.
Uso avanzato di C.
Tipi di dato astratti Lista, Pila, Coda, Albero.
Estendere i linguaggi: i tipi di dato astratti
Strutture dati lineari
Classi ed Oggetti in Java (Cenni). Richiami Ruolo delle Classi in Java Oggetti.
Liste di Interi Esercitazione. Liste Concatenate Tipo di dato utile per memorizzare sequenze di elementi di dimensioni variabile Definizione tipicamente.
LIP: 1 Marzo 2005 Classe Object e Vettori. Partiamo da Lesercizio dellultima esercitazione realizzato tramite array Vedremo come si puo fare in modo piu.
Fondamenti di Informatica I CDL in Ingegneria Elettronica - A.A CDL in Ingegneria Elettronica - A.A Strutture dati dinamiche.
Fondamenti di Informatica I CDL in Ingegneria Elettronica - A.A CDL in Ingegneria Elettronica - A.A Strutture dati dinamiche.
Introduzione al linguaggio C Dr. Francesco Fabozzi Corso di Informatica.
UD 3: “Le Liste” UD 4: “Pile e Code” UD 5: “Alberi e grafi”
Lez. 91 Universita' di Ferrara Facolta' di Scienze Matematiche, Fisiche e Naturali Laurea Specialistica in Informatica Algoritmi Avanzati Alberi di ricerca.
Hash Tables Indirizzamento diretto Tabelle Hash Risoluzioni di collisioni Indirizzamento aperto.
Strutture dati elementari
Indirizzi delle variabili A ogni variabile sono associati tre concetti fondamentali: il valore memorizzato; il tipo dati di appartenenza; lindirizzo. Il.
Fondamenti di Informatica II Ingegneria Informatica / Automatica (A-I) Meccanica Prof. M.T. PAZIENZA a.a – 3° ciclo.
Argomenti dalla linea dei comandi Gli argomenti possono essere passati a qualsiasi funzione di un programma, compresa la main(), direttamente dalla linea.
Fondamenti di Informatica II Ingegneria Informatica / Automatica (A-I) Meccanica Prof. M.T. PAZIENZA a.a – 3° ciclo.
Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a
1 FONDAMENTI DI INFORMATICA II Ingegneria Gestionale a.a ° Ciclo Liste.
PROGRAMMI DI RICERCA E ORDINAMENTO
Fondamenti di Informatica II Ingegneria Informatica (A-I) Prof. M.T. PAZIENZA a.a – 3° ciclo.
STRUTTURE DATI e LABORATORIO II ESERCITAZIONE N°13 Heap massimo.
Esercizi su alberi binari
Tail recursion: esempio
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Corso di Fondamenti di Programmazione a.a.2009/2010 Prof.ssa Chiara Petrioli Corso.
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 Corso di Programmazione 1 a.a.2007/2008 Prof.ssa Chiara Petrioli Corso di Laurea.
Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI
E.Mumolo. DEEI Introduzione alla programmazione ad oggetti in C++ Object Oriented Programming, OOP E.Mumolo. DEEI
Allocazione dinamica della memoria
Laboratorio di Linguaggi lezione VI: puntatori 2/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.
Laboratorio di Linguaggi lezione VII: puntatori 3/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.
Modello dati ALBERO Albero: Albero: insieme di punti chiamati NODI e linee chiamate EDGES EDGE: linea che unisce due nodi distinti Radice (root): in una.
Esercizi su code Date due code in ingresso a valori interi in ordine crescente, scrivere una funzione che restituisca una terza coda che contenga i valori.
nome: sequenza di caratteri usata per denotare un oggetto
memoria gestita staticamente:
1 Strutture Dinamiche Corso di Informatica A Vito Perrone.
Elementi di programmazione ad oggetti a. a. 2009/2010 Corso di Laurea Magistrale in Ingegneria Elettronica Docente: Mauro Mazzieri, Dipartimento di Ingegneria.
1.Scrivere una funzione per cercare un numero x in una lista circolare di interi. La funzione deve restituire NULL se il numero non esiste. 2.Scrivere.
1 ListaDiElem Cancella( ListaDiElem lista, TipoElemento elem ) { ListaDiElem puntTemp; if( ! ListaVuota(lista) ) if( lista–>info == elem ) { puntTemp =
2000 Prentice Hall, Inc. All rights reserved. Capitolo 12 (Deitel) Le strutture dati dinamiche Sommario Introduzione Allocazione dinamica.
Strutture dati per insiemi disgiunti
15 maggio 2002 Avvisi: Ultima lezione: mercoledì 29 maggio II Esonero: mercoledì 5 giugno, ora da stabilire.
Corso di informatica Athena – Periti Informatici
Unità Didattica 3 Linguaggio C
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 Corso di Programmazione 1 a.a.2007/2008 Prof.ssa Chiara Petrioli Corso di Laurea.
Esercizi Liste.
Esercizi su File e Liste
Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a
Fondamenti di Informatica II Ingegneria Informatica / Automatica (A-I) Meccanica Prof. M.T. PAZIENZA a.a – 3° ciclo.
Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 5 Le strutture informative Corso di Informatica 2 a.a. 2003/04 Lezione 5.
Struttura di una lista legata Una lista legata è una variabile strutturata in cui ogni elemento mantiene l’indirizzo (mediante un puntatore) dell’elemento.
Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a
Fondamenti di Informatica II Ingegneria Informatica / Automatica (A-I) Meccanica Prof. M.T. PAZIENZA a.a – 3° ciclo.
Esercitazione su Vector. Permette di definire collezioni di dati generiche, che sono in grado di memorizzare elementi di ogni sottotipo di Object Definito.
Università di Torino – Facoltà di Scienze MFN Corso di Studi in Informatica Programmazione I - corso B a.a prof. Viviana Bono Blocco 7 – Array.
Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a
Fondamenti di Informatica II Ingegneria Informatica (A-I) Prof. M.T. PAZIENZA a.a – 3° ciclo.
Algoritmi e Strutture Dati Strutture Dati Elementari.
MODULO STRUTTURE DATI FONDAMENTALI: Strutture dinamiche
Relazione sulle strutture dati Svolta da: Buccella Simone Strutture di dati Aree di memoria Puntatore numericibooleani alfabetici Statici dinamici Puntatori.
1 FONDAMENTI DI INFORMATICA II Ingegneria Gestionale a.a ° Ciclo Strutture Dati.
1 Il linguaggio C Precisazioni sull’esperienza in laboratorio.
Liste Concatenate 11 Aprile E’ una delle strutture dati fondamentali in tutti i linguaggi di programmazione di alto livello Una Lista Concatenata.
1 Un esempio con iteratore: le liste ordinate di interi.
1 MODULO STRUTTURE DATI FONDAMENTALI: Strutture dinamiche classe 4° INDUSTRIALE ABACUS Ud1Strutture dati lineariTempi -Liste semplicemente puntate 3h+3h.
13. Strutture dati dinamiche Ing. Simona Colucci Informatica - CDL in Ingegneria Industriale- A.A
1 MODULO STRUTTURE DATI FONDAMENTALI: Strutture dinamiche classe 4° INDUSTRIALE INFORMATICA Focus on.
Transcript della presentazione:

Fondamenti di Informatica II Ingegneria Informatica / Automatica (A-I) Meccanica Prof. M.T. PAZIENZA a.a – 3° ciclo

Liste Una lista è una struttura dati ricorsiva (formata da elementi dello stesso tipo e collegati insieme) la cui lunghezza può variare dinamicamente. I suoi elementi so no variabili dinamiche che vengono creati e/o distrutti a tempo di esecuzione producendo una struttura dati che cresce o diminuisce a seconda delle esigenze del programma in esecuzione. E possibile implementare liste tramite array, ma ciò può avvenire solo quando si conoscono esattamente le dimensioni della lista.

Liste Ogni elemento di una lista è definito come una struttura costituita da uno o più campi dati e da un campo puntatore contenente lindirizzo dellelemento successivo. struct elem { int info; elem * succ ; } ;

Strutture concatenate Una struttura é detta concatenata quando é costituita, oltre che dai suoi normali membri, anche da uno o più membri aggiuntivi, dichiarati come puntatori alla struttura stessa. struct rec {int info; rec*next; }; La definizione di una struttura concatenata é di solito accompagnata da un certo numero di funzioni, che hanno il compito di gestirla, cioè eseguire le operazioni di inserimento, di eliminazione e di ricerca di oggetti.

Liste Ogni lista è definita da una variabile puntatore che punta al primo elemento della lista. Nel caso di assenza di elementi (lista vuota) tale variabile puntatore assume valore NULL. In una lista il campo puntatore dellultimo elemento assume sempre valore NULL.

Liste 0 Dati Puntatore alla lista Puntatore al sucessivo Ultimo elemento Dati struct rec { int info; rec* next; }; lislis-> infolis->next

Tipi di Lista Lista circolare (lultimo puntatore non ha valore NULL, ma punta al primo nodo) Lista doppia (può essere visitata nei due sensi -> presenza di due puntatori per nodo) Lista doppia circolare (il puntatore allelemento successivo dellultimo nodo punta al primo elemento della lista e il puntatore allelemento precedente del primo punta allultimo elemento della lista)

Allocazione dinamica di liste Lallocazione dinamica della memoria si presta alla gestione di liste di oggetti, quando il loro numero non é definito a priori. Queste liste possono aumentare e diminuire di dimensioni dinamicamente in base al flusso del programma, e quindi devono essere gestite in un modo più efficiente dellallocazione di memoria permanente sotto forma di array

Liste concatenate Una lista concatenata (linked list) é un insieme di oggetti, caratterizzati dal fatto di essere istanze di una struttura concatenata. In ogni oggetto, i membri puntatori alla struttura contengono lindirizzo di altri oggetti della lista, creando così un legame fra gli oggetti e rendendo la stessa lista percorribile, anche se gli oggetti non sono allocati consecutivamente in memoria. Se la struttura possiede un solo membro puntatore a se stessa, la lista é detta single-linked, se ne possiede due, é detta double-linked.

Inserimento in testa 0 dato 0 0 tempp rec* tempp= new rec; tempp->info = dato; tempp->next = lis; lis = tempp; lis tempp lis tempp lis

Estrazione dalla testa rec* tempp= lis; lis = lis->next; tempp->next = NULL; tempp lis tempp lis 0 tempp lis

Operazioni su liste Creazione della lista (vuota e successivi inserimenti) Lettura di una lista Stampa di una lista Cancellazione di una lista Inserimento in lista Estrazione da lista

Creazione della lista Per creare una lista, basta definirla, ovvero è sufficiente creare il modo di riferirsi ad essa. Lunica cosa che esiste sempre della lista è la sua testa (o radice) ossia il puntatore al suo primo elemento. Questa è lunica componente allocata staticamente ed è inizializzata a NULL poiché allinizio non punta a niente in quanto non ci sono elementi. Es.: rec* lis=NULL ; Puntatore alla lista lisNUL L

Creazione di un nuovo nodo La creazione di un nuovo nodo (in qualunque fase dellesistenza di una lista) avviene creando una nuova istanza della struttura tramite allocazione dinamica, utilizzando di solito un puntatore dappoggio ( tempp ) Es.: rec* tempp = new rec; tempp infonext

Assegnazione di valori ai campi dati Lassegnazione di valori ai campi dati si ottiene dereferenziando il puntatore al nodo e accedendo ai singoli dati, ovvero utilizzando direttamente loperatore -> Es.: tempp->info=7; tempp infonext 7

rec* LeggiListaR() { int val; cin >> val; if (val == 0) return NULL; else { rec* l = new rec; l->info = val; l->next = LeggiListaR(); return l; } Lettura lista versione ricorsiva Nodo lista Lettura di una lista rec* LeggiListaI() { int val; cin >> val; if (val == 0) return NULL; else { rec* l = new rec; l->info = val; rec* ll = l; cin >> val; while (val != 0) { ll->next = new rec; ll = ll->next; ll->info = val; cin >> val; } ll->next = NULL; return l; } Lettura lista versione iterativa

void StampaListaR(rec* l) { if (l ==NULL) cout << endl; else { cout info << ' '; StampaListaR(l->next); } Stampa lista versione ricorsiva Nodo lista Stampa di una lista void StampaListaI(rec* l) { while (l != NULL) { cout info << ' '; l = l->next; } cout << endl; } Stampa lista versione iterativa

void CancellaListaR(rec*& l) { if (l != NULL) { CancellaListaR(l->next); delete l; l = NULL; } Cancellazione lista versione ricorsiva Nodo lista Cancellazione di una lista void CancellaListaI(rec*& l) { while (l != NULL) { rec* ll = l; l = l->next; delete ll; } l = NULL; } Cancellazione lista versione iterativa

#include struct rec { int info; rec* next; }; void main() { rec* lis; lis = LeggiListaR(); StampaListaR(lis); CancellaListaR(lis); lis = LeggiListaI(); StampaListaI(lis); CancellaListaI(lis); } Programma Chiamante Esempio

Inserimento in lista Le operazioni di inserimento di un elemento (ed analogamente quelle di cancellazione) possono avvenire secondo diverse modalità, (ovvero in diverse posizioni della lista) assumendo di volta in volta caratteristiche specifiche.

Inserimento di un nuovo elemento In ogni caso linserimento di un nuovo elemento nella lista prevede sempre i seguenti passi: 1) Creazione di un nuovo nodo (allocazione dinamica) 2) Assegnazione di valori ai campi dati 3) Collegamento del nuovo elemento alla lista esistente aggiornamento del campo puntatore del nodo aggiornamento dei puntatori della lista Queste due ultime operazioni caratterizzeranno la tipologia dell inserimento

Creazione di un nuovo nodo La creazione di un nuovo nodo (in qualunque fase dellesistenza di una lista) avviene creando una nuova istanza della struttura tramite allocazione dinamica, utilizzando di solito un puntatore dappoggio ( tempp ) Es.: rec* tempp = new rec; tempp infonext

Assegnazione di valori ai campi dati Lassegnazione di valori ai campi dati si ottiene dereferenziando il puntatore al nodo e accedendo ai singoli dati, ovvero utilizzando direttamente loperatore -> Es.: tempp->info=7; tempp infonext 7

Inserimento in testa Il caso più semplice è costituito dall inserimento in testa, in quanto si dispone di un riferimento esplicito a questa (il puntatore alla lista lis). Il campo next del nuovo nodo punterà allo stesso valore di lis lis punterà al nuovo nodo tempp->next=lis; lis=tempp; NB. Funziona anche se la lista è vuota!

Inserimento in testa 0 dato 0 tempp tempp->next = lis; lis = tempp; lis tempp lis tempp lis 0 0 dato 0 0 tempp lis 0 tempp

Inserimento in coda Linserimento in coda è più complesso, in quanto non abbiamo un puntatore esplicito allultimo elemento, ma dobbiamo prima scorrere la lista per cercarlo. Supponiamo di averlo trovato e che sia il puntatore p: Il campo next del nuovo nodo punterà a NULL (in quanto è lultimo) Il campo next dellex ultimo nodo punterà al nuovo nodo Es.: tempp->next=NULL; p->next=tempp; La lista vuota va gestita come un caso particolare!

Ricerca dellultimo elemento Per cercare lultimo elemento, possiamo scorrere la lista tramite un puntatore ausiliario p, inizializzato a lis. Es: rec* p= lis; while (p->next != NULL) p=p->next; Dove è lerrore ??

Ricerca dellultimo elemento La condizione (p->next != NULL) nel caso la lista sia vuota conduce ad un errore fatale in quanto si sta dereferenziando un puntatore nullo. Questo è un tipico errore che si fa nella gestione delle strutture dinamiche!!! 0 lis 0 p p->next 0 p p->next = ??

Ricerca dellultimo elemento La procedura corretta è: rec* p= lis; while (p!=NULL && p->next != NULL) p=p- >next; 0 lis 0 p p->next 0 p

Inserimento in coda 0 lis 0 p 0 p 0 datotempp 0 dato tempp lis p 0 datotempp lis 0 p 0 dato tempp tempp->next = p; (o NULL) p->next = tempp; lis = tempp;

Inserimento in una posizione specifica Linserimento in una posizione specifica richiede preventivamente lindividuazione di tale posizione allinterno della lista e dipende dalla condizione che si vuole verificare, per cui dobbiamo prima scorrere la lista per determinarla. Vediamo ad esempio come comportarsi per inserire i valori in ordine crescente.

Inserimento ordinato dei valori Nel caso di inserimento in ordine crescente, la lista risultante deve rimanere in ogni momento ordinata. Pertanto, allinserimento di un nuovo valore, si dovrà scorrere la lista fino alla posizione corretta per linserimento (fin quando cioè il campo info dei nodi esistenti risulta minore del dato da inserire).

Ricerca di un elemento qualsiasi La condizione più sicura da utilizzare in una ricerca è riferirsi direttamente al puntatore allelemento nella condizione di scorrimento. In tal modo però si sorpassa lelemento cercato. Per questo nella ricerca della posizione di inserimento si usano di solito due puntatori, p e q, che puntano rispettivamente allelemento precedente e al successivo. Es: rec* q= lis; rec* p= lis; while (q != NULL && q->info dato) {p=q; q=q->next;}

Ricerca di una posizione specifica rec* q= lis; rec* p= lis; while (q != NULL && q->info dato) {p=q; q=q->next;} 2 lis p q 7tempp lis p q

Casi particolari rec* q= lis; rec* p= lis; while (q != NULL && q->info dato) {p=q; q=q->next;} 8 lis p q 7tempp lis p q Se q==lis allora p non contiene lelemento precedente

Inserimento ordinato dei valori Quindi nel caso generale: tempp-> next = q; p->next = tempp; ma se q==lis (inserimento in testa) lis=tempp

Inserimento ordinato dei valori 2 lis p q 7tempp lis p q 7tempp tempp->next =q p->next =tempp

void instesta(rec*& lis, int a) { rec* p = new rec; p->info = a; p->next = lis; lis = p; } Inserimento in testa Inserimento in lista void insfondo(rec*& lis, int a) { rec* p = lis; for (rec* q = p; q != NULL; q = q->next) p = q; q = new rec; q->info = a; q->next = NULL; if (p != NULL) p->next = q; else lis = q; } Inserimento in coda

Inserimento in ordine crescente (info) void inscresc(rec*& lis, int a) { rec* p = lis; for (rec* q = p; q != NULL && q->info next) p = q; rec* r = new rec; r->info = a; r->next = q; if (q != lis) p->next = r; else lis = r; } Inserimento in ordine crescente

Eliminazione di un nodo dalla lista Leliminazione di un nodo dalla lista prevede: Ricerca del nodo da eliminare (se necessaria) Salvataggio del nodo in una variabile ausiliaria (per passo 4) Scollegamento del nodo dalla lista (aggiornamento dei puntatori della lista) Distruzione del nodo (deallocazione della memoria) In ogni caso, bisogna verificare che la lista non sia già vuota! if (lis != NULL) …

Ricerca del nodo da eliminare Dipende dalle esigenze del programma. Come per linserimento, il caso più semplice è costituito dalleliminazione del nodo di testa, in quanto esiste il puntatore lis a questo elemento. Negli altri casi, si procede come per linserimento

Scollegamento del nodo dalla lista Individuato il nodo, bisogna evitare che la sua rimozione spezzi la lista. In generale, è necessario aggiornare il puntatore next dellelemento precedente lis 0 0 0

Eliminazione del nodo di testa Bisogna aggiornare il puntatore alla testa lis che dovrà puntare al nodo successivo a quello da eliminare. rec* tempp=lis; (salvataggio nodo da eliminare) lis = tempp->next; (aggiornamento lista) delete tempp; (distruzione nodo)

Eliminazione del nodo di coda Bisogna aggiornare il campo next relativo al penultimo nodo, che ora diventa lultimo (e quindi assume valore NULL). Per la ricerca dellultimo elemento si usano due puntatori p e q, che puntano rispettivamente al penultimo e allultimo elemento. La condizione sarà: rec* q= lis; rec* p= lis; while (q != NULL && q->next != NULL) {p=q; q=q->next;} Casi particolari: lelemento da eliminare è lunico della lista.

Eliminazione del nodo di coda rec* q= lis; rec* p= lis; while (q != NULL && q->next != NULL) {p=q; q=q->next;} lis p q 0 0 p q Se q==lis allora p non contiene lelemento precedente

Eliminazione del nodo di coda lis p q 0 tempp lis p q 0 0 tempp rec* tempp =q; p->next = tempp->next ; oppure p->next = NULL;

Eliminazione del nodo di coda lis p q 0 tempp rec* tempp = q; lis = tempp->next; oppure lis = NULL; lis p q 0 0

BOOL esttesta(rec*& lis, int& a) { rec* p = lis; if (lis != NULL) { a = lis->info; lis = lis->next; delete p; return T; } return F; } Estrazione dalla testa Estrazione da lista

BOOL estfondo(rec*& lis, int& a) { rec* p = lis; if (lis != NULL) { for (rec* q = p; q->next != NULL; q = q->next) p = q; a = q->info; if (q == lis) lis = NULL; else p->next = NULL; delete q; return T; } return F; } Estrazione dal fondo

Estrazione da lista BOOLEAN togli(rec*&lis, int a) { rec* p = lis; for (rec* q = p; q != NULL && q->info != a; q = q->next) p = q; if (q != NULL) { if (q == lis) lis = p->next; p->next = q->next; delete q; return T; } return F; } Estrazione di un elemento specifico

Inserimento in lista void insfondoR(rec*& lis, int a) { if (lis != NULL) insfondoR(lis->next,a); else { rec* p = new rec; p->info = a; p->next = NULL; lis=p } Inserimento in fondo versione ricorsiva void inscrescR(rec*& lis, int a) { if (lis != NULL && lis->info < a) inscrescR(lis->next,a); else { rec* p = new rec; p->info = a; p->next = lis; lis=p } Inserimento in ordine versione ricorsiva

Estrazione da lista BOOL estfondoR(rec*& lis, int& a) { if (lis != NULL) { if (lis->next != NULL) return estfondoR(lis->next,a); else { a= lis->info; delete lis; lis = NULL; return T; } else return F; } Estrazione dal fondo versione ricorsiva BOOL togliR(rec*& lis, int a) { if (lis != NULL) { if (lis->info != a) return togliR(lis->next,a); else { rec* p = lis; lis = lis->next; delete p; return T; } else return F; } Estrazione di un elemento specifico versione ricorsiva