Scaricare la presentazione
La presentazione è in caricamento. Aspetta per favore
PubblicatoAlda Fiore Modificato 10 anni fa
1
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 di Laurea in Informatica Università degli Studi La Sapienza (lezioni 16-19) Strutture, Unioni e Liste
2
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Strutture Le strutture sono collezioni di variabili correlate sotto un unico nome Possono contenere variabili di diversi tipi di dato Esempio struct card{ char *face; char *suit; }; Definisce un tipo di dato struttura struct card costituita da due campi un campo face stringa che dice che carta è quella corrente: asso, due,…,re un campo suit stringa che dice il seme della carta corrente (cuori,…,fiori) Membri di una struttura Etichetta di una struttura
3
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Esempio Il recordi di un impiegato struct impiegato{ char *nome; char *cognome; int eta; char sesso; float stipendio; }; La struttura consente di raggruppare Informazioni correlate, in questo caso Relative ad un singolo impiegato
4
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Dichiarazione di variabili struct struct card a, deck[52], *cPtr; a è una variabile di tipo struct card viene allocata memoria per due campi puntatori deck è un vettore di strutture. Contiene 52 elementi. Ciascun elemento è una struttura costituita da due campi face e suit cPtr è un puntatore ad una struttura (contiene lindirizzo della locazione di memoria in cui è memorizzato un elemento di tipo struct card)
5
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Dichiarazione di variabili struct struct card a, deck[52], *cPtr; a è una variabile di tipo struct card viene allocata memoria per due campi puntatori deck è un vettore di strutture. Contiene 52 elementi. Ciascun elemento è una struttura costituita da due campi face e suit cPtr è un puntatore ad una struttura (contiene liundirizzo della locazione di memoria in cui è memorizzato un elemento di tipo struct card) ALTERNATIVA struct card{ char *face; char *suit; }a,deck[52],*cPtr;
6
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Operazioni su strutture Assegnare variabili struct a variabili struct dello stesso tipo di struttura Determinare in che locazione di memoria è memorizzata una struttura Accedere ai membri di una struttura (per leggere o scrivere il loro valore) Con loperatore sizeof determinare la dimensione di una struttura (cosa che serve ad esempio per sapere quanta memoria deve essere allocata a ciascun elemento di quel tipo di dato struttura)
7
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Operazioni illecite Due elementi di tipo struttura non possono essere confrontati – Ci possono essere dei bit con valore indeterminato nelle locazioni di memoria allocate ad una struttura –Ad esempio struct example{ char c; int i; } sample1,sample2; Un computer con una parola di 2byte potrebbe richiedere lallineamento allinizio della parola successiva per membri successivi della struttura 01100001 00000000 Buco. In questo byte potrebbe essere contenuto qualsiasi valore impossibile confrontare sample1 e sample2 direttamente. Bisogna confrontare i valori dei vari membri delle due strutture.
8
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inizializzazione di strutture struct card{ char *face; char *suit; }; struct card a={Asso,Fiori}; Se il valore di un membro non è indicato tra le parentesi graffe è inizializzato automaticamente a 0 (o a NULL se è di tipo puntatore).
9
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Come si accede ai membri di una struttura Operatore membro di struttura (operatore punto.) – accede ad un membro della struttura attraverso il nome della variabile di struttura Esempio printf(%s, a.suit); Stampa il campo suit della variabile a, di tipo struct card
10
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Come si accede ai membri di una struttura Operatore puntatore a struttura -> – accede ad un membro della struttura attraverso un puntatore alla stessa Esempio printf(%s, cPtr->suit); Stampa il campo suit della struttura puntata da cPtr. cPtr è un puntatore ad una struttura di tipo struct card cPtr->suit equivale a (*cPtr).suit le parentesi sono necessarie perché loperatore membro di struttura ha priorità maggiore di * Risolve il riferimento e accede al membro suit della struttura usando loperatore membro di struttura
11
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Un esempio #include<stdio.h> struct card{ char *face; char *suit; };main(){ struct card a; struct card *aPtr; a.face =Asso; a.suit=Picche;aPtr=&a; printf(%s di %s\n%s di %s\n %s di %s \n, a.face, a.suit, aPtr->face, aPtr->suit, (*aPtr).face, (*aPtr).suit); return 0; } Asso di Picche
12
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Esempio Il recordi di un impiegato struct impiegato{ char *nome; char *cognome; int eta; char sesso; float stipendio; }; La struttura consente di raggruppare Informazioni correlate, in questo caso Relative ad un singolo impiegato
13
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Usare le strutture con le funzioni Le strutture possono essere passate alle funzioni fornendo i singoli membri, lintera struttura o un puntatore ad una struttura. Vettori di strutture sono passati per riferimento. Per passare una struttura per riferimento si deve passare alla funzione lindirizzo di memoria dove è memorizzata la struttura. Le funzioni possono restituire strutture Passati per valore Può consentire ad una funzione di restituire più valori
14
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Un esempio Si scriva una funzione che dato un vettore restituisca il più piccolo elemento del vettore ed il più grande elemento del vettore Definiamo: struct min_max{ int min; int max; };
15
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010Soluzione struct min_max minmax_v (int vett[ ], int n) { struct min_max temp; if (n==1) {temp.min=vett[0];temp.max=vett[0]; return temp; }else{temp=minmax_v(vett,n-1); if (vett[n-1]<temp.min) temp.min=vett[n-1]; if (vett[n-1]>temp.max) temp.max=vett[n-1]; return temp; }} La funzione minmax_v prende in input un vettore di interi vett e la sua dimensione n restituisce in output una struttura di tipo min_max che contiene nei suoi membri il minimo ed il massimo tra gli elementi del vettore
16
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Come si può passare per valore un vettore Dobbiamo creare una struttura che contenga come membro il vettore Dato che una struttura o i membri della struttura sono passati per valore il vettore verrà passato nello stesso modo (basta passare alla funzione il membro della struttura che contiene il vettore) – Verrà quindi fatta una copia del vettore e si opererà su tale copia
17
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010typedef La parola chiave typedef consente di creare pseudonimi per i tipi di dato precedentemente definiti, tipicamente per abbreviare i nomi di tali tipi di dato typedef struct card Card; dice che nel seguito del programma quando si troverà scritto Card di farà riferimento al tipo struct card Card deck[52]; Card NON è un nuovo tipo di dato, è un sinonimo per struct card !
18
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010Esempio Mescolatore di carte (variante ad alta efficienza di quello precedentemente visto) Vettore di tipo Card fillDeck inizializzato in modo da contenere le carte ordinate dallasso al re per ogni seme La funzione shuffle che mescola il mazzo riceverà come input un vettore di 52 strutture di tipo Card, scorrerà le carte e per ogni carta sceglierà un numero casuale tra 0 e 51 (carta con cui la carta esaminata sarà scambiata). Mescola effettuando scambi, non potendo portare ad attese lunghe o indefinite per il completamento.
19
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010Codice #include #include #include<stdlib.h>#include<time.h> struct card { char *face; char *suit; }; typedef struct card Card; void fillDeck (Card *,char *[ ], char *[ ]); void shuffle(Card *); void deal(Card *);
20
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010Codicemain(){ Card deck[52]; char *face[ ]={Asso, Due, Tre, Quattro, Cinque, Sei, Sette, Otto, Nove, Dieci, Fante, Donna, Re}; char *suit[ ]={Cuori, Quadri, Picche, Fiori}; srand(time(NULL)); fillDeck(deck, face, suit); shuffle(deck);deal(deck); return 0; } Deck è un vettore di strutture
21
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Codice void fillDeck(Card *wDeck, char *wFace[ ], char *wSuit[ ]) { int i; for (i=0;i<=51;i++) {wDeck[i].face=wFace[i%13];wDeck[i].suit=wSuit[i/13];}} Inizializziamo al caso in cui per ciascun seme le carte sono ordinate
22
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010Codice void shuffle(Card *wDeck) { int i,j; Card temp; for (i=0;i<=51;i++){ j=rand()%52;temp=wDeck[i];wDeck[i]=wDeck[j];wDeck[j]=temp;}}
23
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Codice void deal (Card *wDeck) { int i; for (i=0;i<=51;i++) printf(%s of %s \n, wDeck[i].face, wDeck[i].suit); }
24
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Strutture di dati dinamiche Abbiamo finora studiato strutture di dati con dimensione fissa – vettori a una o due dimensioni – struct Vedremo in queste lezioni un esempio di struttura di dati dinamica (lista) – le dimensioni della struttura crescono e decrescono durante lesecuzione del programma a seconda delle esigenze (a seconda che venga aggiunto o eliminato un elemento)
25
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Strutture ricorsive Una struttura ricorsiva contiene un membro di tipo puntatore che fa riferimento ad una struttura dello stesso tipo di quella in cui è contenuto Esempio struct node{ int data; struct node *nextPtr; }; nextPtr punta a struct node ovvero ad una struttura dello stesso tipo di quella che stiamo dichiarando Struttura ricorsiva 152 NULL
26
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Allocazione dinamica della memoria Indica la capacità di un programma di ottenere durante la sua esecuzione un maggior spazio di esecuzione per immagazzinare i nuovi elementi delle strutture di dati dinamiche e la capacità di rilasciare memoria quando elementi di tali strutture vengono cancellati – Funzioni malloc malloc free free sizeof sizeof
27
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Allocazione dinamica della memoria (malloc) La funzione malloc prende come argomento il numero di byte che dovranno essere allocati, alloca memoria consecutiva per questo numero di byte e restituisce un puntatore a void (void *) allarea di memoria allocata (NULL se non può essere allocata memoria) Un puntatore a void void * può essere assegnato ad una variabile di tipo puntatore qualsiasi Esempio di uso: newPtr=malloc(sizeof(struct node)); Alloca memoria sufficiente a contenere un nuovo elemento di tipo struct node; restituisce lindirizzo dellarea di memoria allocata; tale indirizzo è memorizzato in newPtr. Restituisce il numero di byte necessari per memorizzare un elemento di tipo struct node
28
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Deallocazione della memoria Quando un elemento viene eliminato è estremamente importante deallocare la memoria associata allelemento Renderla disponibile al sistema in modo che la stessa/le stesse locazioni di memoria possano essere usate nuovamente in futuro Renderla disponibile al sistema in modo che la stessa/le stesse locazioni di memoria possano essere usate nuovamente in futuro Nel caso di allocazione dinamica la deallocazione deve essere fatta esplicitamente con Nel caso di allocazione dinamica la deallocazione deve essere fatta esplicitamente confree(newPtr); tale funzione dealloca la memoria puntata da newPtr. (per sapere quanta memoria deallocare qui serve che newPtr sia un puntatore a un certo tipo specifico di dato)
29
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010Liste Una lista concatenata è una collezione di strutture ricorsive (nodi) connesse da puntatori (detti anche collegamenti o link). La lista avrà un puntatore alla testa della lista (primo elemento). Agli altri elementi si accede per mezzo dei puntatori che collegano un elemento al successivo Il puntatore dellultimo elemento inserito deve essere posto a NULL in modo da consentire di riconoscere la fine della lista. 152 NULL
30
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Esempio struct node *Lista; Lista sarà inizializzata in modo da puntare alla testa della lista (conterrà il valore 4200, ovvero lindirizzo della locazione di memoria in cui è contenuto il primo elemento) 152 NULL 4200 3700
31
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Esempio struct node *Lista; Lista->data consentirà di accedere al valore memorizzato nel primo elemento (15) Lista->nextPtr conterrà lindirizzo del prossimo elemento della lista 152 NULL 4200 3700
32
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010Esempio struct node *Lista; Seguendo i puntatori nextPtr è possibile accedere uno dietro laltro ai vari elementi della lista Gli elemento di una lista NON sono memorizzati consecutivamente in memoria ma un elemento sa dove è memorizzato lelemento successivo 152 NULL 4200 3700
33
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010Esempio struct node *Lista; Un elemento può contenere dati di ogni tipo (incluse altre struct) Gli elementi vengono aggiunti e cancellati dinamicamente. 152 NULL 4200 3700
34
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Vantaggi e svantaggi delluso di liste concatenate Pro: se non è possibile determinare a priori il numero di elementi della collezione le liste concatenate consentiranno di far crescere o decrescere a seconda delle necessità la lista – Un vettore può dover sovraallocare la memoria portando a sprechi (la memoria allocata pone comunque nel caso di vettori un limite alla crescita della collezione) –Cancellare elementi in un vettore è complesso, richiede di spostare gli elementi successivi di una posizione indietro. Cancellare e aggiungere elementi è facile nelle liste concatenate –E possibile inserire in modo ordinato gli elementi
35
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Vantaggi e svantaggi delluso di liste concatenate Con:mentre per un vettore gli elementi sono memorizzati consecutivamente in memoria (accedere allelemento che corrisponde ad un indice è una operazione che richiede tempo costante) accedere ad un elemento in una lista richiede di scandire la lista fino a quellelemento.
36
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Esercizi su liste struct nodo { int elem; struct nodo * next; }; typedef struct nodo L_ELEM; typedef struct nodo * L_PTR;
37
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Operazioni sulle liste Vedremo le seguenti operazioni – Verifica se la lista è vuota –Inserimento in testa ad una lista –Inserimento in una lista ordinata –Cancellazione di un elemento in una lista – Verifica se una lista è ordinata –Stampa di una lista –Somma degli elementi di una lista –Numero di occorrenze di un valore in una lista
38
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Esercizio 1 Si scriva una funzione che, data una lista di Interi ed un valore inserisca un nuovo Elemento contenente Il valore in testa alla lista /*inserisci un nuovo elemento in testa alla lista*/ L_PTR inserisci_in_testa(L_PTR L1, int val) { L_PTR temp_ptr; temp_ptr=malloc(sizeof(L_ELEM)); if (temp_ptr!=NULL) { temp_ptr->elem=val; temp_ptr->elem=val; temp_ptr->next=L1; temp_ptr->next=L1; L1=temp_ptr; L1=temp_ptr; }else printf("memoria non disponibile per l'elemento della lista \n"); printf("memoria non disponibile per l'elemento della lista \n"); return L1; }
39
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cosa succede in memoria… L_PTR inserisci_in_testa(L_PTR L1, int val) {………….} NULL L2 3 7 54 2800570013006900 Indirizzo di memoria In cui e memorizzato Questo elemento L2 (di tipo L_PTR) ha associata una locazione di memoria che contiene lindirizzo del primo elemento della lista 2800 L2 L2->next contiene lindirizzo di memoria del prossimo elemento della lista (5700) Vediamo ora cosa succede se dal main viene invocato: L2=inserisci_in_testa(L2,v) dove v vale 5
40
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cosa succede in memoria… L_PTR inserisci_in_testa(L_PTR L1, int val) {………….} NULL L2 3 7 54 Indirizzo di memoria In cui e memorizzato Questo elemento L1 Vediamo ora cosa succede se dal main viene invocato: L2=inserisci_in_testa(L2,v) dove v vale 5…. Quando viene invocata la funzione viene allocata memoria per gli argomenti della funzione (L1 e val) val 2800570013006900
41
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cosa succede in memoria… L_PTR inserisci_in_testa(L_PTR L1, int val) {………….} NULL L2 3 7 54 L1 Vediamo ora cosa succede se dal main viene invocato: L2=inserisci_in_testa(L2,v) dove v vale 5…. Quando viene invocata la funzione viene allocata memoria per gli argomenti della funzione (L1 e val). val In L1 viene copiato il valore di L2 2800 In val viene copiato il valore di v 5 2800570013006900
42
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cosa succede in memoria… L_PTR inserisci_in_testa(L_PTR L1, int val) {L_PTR temp_ptr; temp_ptr=malloc(sizeof(L_ELEM));temp_ptr->elem=val; temp_ptr->next=L1; temp_ptr->next=L1; L1=temp_ptr; L1=temp_ptr; return L1; } NULL L2 3 7 54 L1 val 2800 5 Alloca memoria per il nuovo elemento 9100 { Nuovo elemento temp_ptr 9100 temp_ptr contiene lindirizzo della posizione di memoria allocata per Il nuovo elemento 2800570013006900
43
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cosa succede in memoria… L_PTR inserisci_in_testa(L_PTR L1, int val) {L_PTR temp_ptr; temp_ptr=malloc(sizeof(L_ELEM));temp_ptr->elem=val; temp_ptr->next=L1; temp_ptr->next=L1; L1=temp_ptr; L1=temp_ptr; return L1; } NULL L2 3 7 54 L1 val 2800 5 Viene inserito il valore val nel campo elem del nuovo elemento Il campo next del nuovo elemento punta a quello che era il primo elemento della lista 9100 { Nuovo elemento temp_ptr 9100 5 2800570013006900
44
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cosa succede in memoria… L_PTR inserisci_in_testa(L_PTR L1, int val) {L_PTR temp_ptr; temp_ptr=malloc(sizeof(L_ELEM));temp_ptr->elem=val; temp_ptr->next=L1; temp_ptr->next=L1; L1=temp_ptr; L1=temp_ptr; return L1; } NULL L2 3 7 54 L19100 L1 viene aggiornato con quello che e lindirizzo della locazione di memoria del nuovo primo elemento della lista. Tale valore viene restituito 9100 { Nuovo elemento temp_ptr 9100 5 val 5 2800570013006900
45
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cosa succede in memoria… L2=inserisci_in_testa(L2,v)} NULL L2 3 7 54 L19100 Il valore ritornato e assegnato a L2 che ora punta (correttamente) al nuovo primo elemento della lista 9100 { Nuovo elemento temp_ptr 9100 5 val 5 2800570013006900
46
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Esercizio 1-bis (potevamo scrivere il codice come segue?) Si scriva una funzione che, data una lista di Interi ed un valore inserisca un nuovo Elemento contenente Il valore in testa alla lista /*inserisci un nuovo elemento in testa alla lista*/ void inserisci_in_testa(L_PTR L1, int val) { L_PTR temp_ptr; temp_ptr=malloc(sizeof(L_ELEM)); if (temp_ptr!=NULL) { temp_ptr->elem=val; temp_ptr->elem=val; temp_ptr->next=L1; temp_ptr->next=L1; L1=temp_ptr; L1=temp_ptr; }else printf("memoria non disponibile per l'elemento della lista \n"); printf("memoria non disponibile per l'elemento della lista \n");} SBAGLIATO!!! Capiamo il perche Manca il return L1; in questo caso la funzione non restituisce nulla
47
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cosa succede in memoria… Void inserisci_in_testa(L_PTR L1, int val) {………….} NULL L2 3 7 54 Indirizzo di memoria In cui e memorizzato Questo elemento L2 (di tipo L_PTR) ha associata una locazione di memoria che contiene lindirizzo del primo elemento della lista 2800 L2 L2->next contiene lindirizzo di memoria del prossimo elemento della lista (5700) Vediamo ora cosa succede se dal main viene invocato: inserisci_in_testa(L2,v) dove v vale 5 2800570013006900
48
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cosa succede in memoria… void inserisci_in_testa(L_PTR L1, int val) void inserisci_in_testa(L_PTR L1, int val){………….} NULL L2 3 7 54 Indirizzo di memoria In cui e memorizzato Questo elemento L1 Vediamo ora cosa succede se dal main viene invocato: inserisci_in_testa(L2,v) dove v vale 5…. Quando viene invocata la funzione viene allocata memoria per gli argomenti della funzione (L1 e val) val 2800570013006900
49
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cosa succede in memoria… Void inserisci_in_testa(L_PTR L1, int val) {………….} NULL L2 3 7 54 L1 Vediamo ora cosa succede se dal main viene invocato: inserisci_in_testa(L2,v) dove v vale 5…. Quando viene invocata la funzione viene allocata memoria per gli argomenti della funzione (L1 e val). val In L1 viene copiato il valore di L2 2800 In val viene copiato il valore di v 5 2800570013006900
50
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cosa succede in memoria… void inserisci_in_testa(L_PTR L1, int val) {L_PTR temp_ptr; temp_ptr=malloc(sizeof(L_ELEM));temp_ptr->elem=val;temp_ptr->next=L1;L1=temp_ptr;} NULL L2 3 7 54 L1 val 2800 5 Alloca memoria per il nuovo elemento 9100 { Nuovo elemento temp_ptr 9100 Temp_ptr contiene lindirizzo della posizione di memoria allocata per Il nuovo elemento 2800570013006900
51
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cosa succede in memoria… L_PTR inserisci_in_testa(L_PTR L1, int val) {L_PTR temp_ptr; temp_ptr=malloc(sizeof(L_ELEM));temp_ptr->elem=val;temp_ptr->next=L1;L1=temp_ptr;} NULL L2 3 7 54 L1 val 2800 5 Viene inserito il valore val nel nuovo elemento Il campo next del nuovo elemento punta a quello che era il primo elemento della lista 9100 { Nuovo elemento temp_ptr 9100 5 2800570013006900
52
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cosa succede in memoria… Void inserisci_in_testa(L_PTR L1, int val) {L_PTR temp_ptr; temp_ptr=malloc(sizeof(L_ELEM));temp_ptr->elem=val; temp_ptr->next=L1; temp_ptr->next=L1; L1=temp_ptr; L1=temp_ptr;} NULL L2 3 7 54 L19100 L1 viene aggiornato con quello che e lindirizzo della locazione di memoria del nuovo primo elemento della lista. Si esce dalla funzione.. 9100 { Nuovo elemento temp_ptr 9100 5 val 5 2800570013006900
53
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cosa succede in memoria… NULL L2 3 7 54 L19100 1) La memoria per L1, temp_ptr e val viene deallocata alluscita dalla funzione 9100 { Nuovo elemento temp_ptr 9100 5 val 5 2) L2 non e stato MAI modificato Contiene quindi lindirizzo di memoria di quello che era prima della chiamata a funzione il primo elemento della lista non ce modo di accedere al nuovo elemento ERRORE!!! 2800570013006900
54
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Allocazione dinamica dei vettori Cosa succede, se non si sa a priori (quando scriviamo il programma) quanti elementi di un array ci serviranno a tempo di esecuzione? La soluzione che abbiamo visto finora prevede di sovraallocare memoria per il vettore non è detto che risponda alle esigenze a run time spreco di risorse Altra soluzione: allocazione dinamica di array.
55
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Allocazione dinamica di vettori (void*) calloc(unsigned int n, unsigned int size); calloc = c ontiguous alloc ation Alloca memoria per n elementi contigui ciascuno di dimensione pari a size. Restituisce un puntatore allarea di memoria allocata. Per il resto, funziona come malloc int* p; p = (int*) calloc(5000,sizeof(int) ); Alloca un vettore di 5000 interi.
56
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Allocazione di vettori Quale la differenza int* v = (int*) calloc(5000,sizeof(int) ); int v[5000]; A) fixed size vector: In entrambi i casi: ho un vettore di 5000 interi posso scrivere ad esempio: v[2]= v[1]++;
57
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Allocazione di vettori Differenza 1: dimensione variabile se x è una variabile intera, posso scrivere: ma non posso scrivere: int* v = (int*) calloc(x,sizeof(int) ); int v[x]; la dimensione di un array statico è una costante la dimensione di un array statico è una costante La memoria allocata deve poi essere esplicitamente deallocata con una free
58
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Differenza tra malloc e calloc (potremmo usare anche la malloc? si) Calloc prende due input e quindi alloca memoria per n elementi di una certa dimensione Calloc prende due input e quindi alloca memoria per n elementi di una certa dimensione Quando invocata la calloc inizializza a zero la memoria allocata, di cui restituisce il puntatore Quando invocata la calloc inizializza a zero la memoria allocata, di cui restituisce il puntatore – Calloc(m, n) corrisponde a p = malloc(m * n); memset(p, 0, m * n); p = malloc(m * n); memset(p, 0, m * n); Riallocazione della memoria con Riallocazione della memoria con – void *realloc(void *ptr, size_t size); Cambia la dimensione delloggetto di memoria puntato da ptr che ora avrà allocata memoria pari a size. Se la nuova dimensione richiede di spostare loggetto la memoria precedentemente allocata è liberata. Dopo lallocazione la prima parte delloggetto di memoria (i primi size elementi se size < della precedente dimensione n, o i primi n elementi altrimenti) mantengono lo stesso valore che avevano prima dellinvocazione della realloc Setta a zero e restituisce p
59
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010
60
Esercizio 2 Si scriva una funzione che, data una lista di Interi ed un valore inserisca un nuovo Elemento contenente Il valore in testa alla lista /*inserisci un nuovo elemento in testa alla lista */ void inserisci_in_testa2 (L_PTR * LISTAPTR, int val) { L_PTR temp_ptr; temp_ptr=malloc(sizeof(L_ELEM)); if (temp_ptr !=NULL) { temp_ptr->elem=val; temp_ptr->elem=val; temp_ptr->next=*LISTAPTR; temp_ptr->next=*LISTAPTR; *LISTAPTR=temp_ptr; *LISTAPTR=temp_ptr; }else printf("memoria non disponibile per l'elemento della lista \n"); } LISTA_PTR e un puntatore a puntatore Ovvero una variabile che contiene lindirizzo di memoria di una variabile di tipo puntatore (che a sua volta contiene lindirizzo di memoria di un Elemento della lista)
61
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cosa succede in memoria… void inserisci_in_testa(L_PTR *LISTAPTR, int val) {………….} NULL L2 3 7 54 L2 (di tipo L_PTR) ha associata una locazione di memoria che contiene lindirizzo del primo elemento della lista 2800 L2 Vediamo ora cosa succede se dal main viene invocato: inserisci_in_testa(&L2,v) dove v vale 5 2800570013006900
62
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cosa succede in memoria… void inserisci_in_testa(L_PTR* LISTAPTR, int val) void inserisci_in_testa(L_PTR* LISTAPTR, int val){………….} NULL L2 3 7 54 LISTAPTR Vediamo ora cosa succede se dal main viene invocato: inserisci_in_testa(&L2,v) dove v vale 5…. Quando viene invocata la funzione viene allocata memoria per gli argomento della funzione (LISTAPTR e val). LISTAPTR e un puntatore a puntatore ovvero contiene lindirizzo della locazione di memoria associata ad una variabile di tipo puntatore. In LISTAPTR viene copiato lindirizzo di L2 (dato che la funzione e invocata con argomento &L2) val 2800 7500 5 2800570013006900
63
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cosa succede in memoria… Void inserisci_in_testa(L_PTR* LISTAPTR, int val) {………….} NULL3 7 54 LISTAPTR Vediamo ora cosa succede se dal main viene invocato: inserisci_in_testa(&L2,v) dove v vale 5…. val 7500 5 temp_ptr=malloc(sizeof(L_ELEM)); if (temp_ptr !=NULL) { temp_ptr->elem=val; temp_ptr->next=*LISTAPTR; *LISTAPTR=temp_ptr; } Viene allocata memoria per un nuovo elemento temp_ptr punta a tale locazione di memoria Nel campo elem di tale locazione viene memorizzato il valore di val temp_ptr 5 3500 L2 2800 7500 2800570013006900
64
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cosa succede in memoria… temp_ptr=malloc(sizeof(L_ELEM)); if (temp_ptr !=NULL) { temp_ptr->elem=val; temp_ptr->elem=val; temp_ptr->next=*LISTAPTR; temp_ptr->next=*LISTAPTR; *LISTAPTR=temp_ptr; *LISTAPTR=temp_ptr; } NULL3 7 54 Al campo next del nuovo elemento viene assegnato *LISTAPTR (ovvero il contenuto della locazione di memoria il cui indirizzo e in LISTAPTR ovvero lindirizzo del primo elemento della lista) LISTAPTR val 7500 5 temp_ptr 5 3500 L2 2800 7500 2800 570013006900
65
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cosa succede in memoria… temp_ptr=malloc(sizeof(L_ELEM)); if (temp_ptr !=NULL) { temp_ptr->elem=val; temp_ptr->elem=val; temp_ptr->next=*LISTAPTR; temp_ptr->next=*LISTAPTR; *LISTAPTR=temp_ptr; *LISTAPTR=temp_ptr; } NULL3 7 54 *LISTAPTR e il contenuto della locazione di memoria il cui indirizzo è memorizzato in LISTAPTR, ovvero il valore di L2. Con listruzione *LISTAPTR=temp_ptr viene modificato L2 che viene fatto puntare al nuovo primo elemento. Alluscita dalla funzione L2 puntera quindi correttamente al nuovo primo elemento della lista. LISTAPTR val 7500 5 temp_ptr 5 3500 L2 3500 7500 2800 570013006900
66
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Operazioni sulle liste Vedremo le seguenti operazioni – Verifica se la lista è vuota –Inserimento in testa ad una lista OK –Inserimento in una lista ordinata –Cancellazione di un elemento in una lista – Verifica se una lista è ordinata –Stampa di una lista –Somma degli elementi di una lista –Numero di occorrenze di un valore in una lista
67
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Esercizio –stampa di una lista Si scriva una procedura che data una lista Ne stampi gli elementi ® /*stampa ricorsiva di una lista*/ void stampalista (L_PTR L1) { if (L1!=NULL) { printf("--> %d ",L1->elem); stampalista(L1->next);}else printf("-->NULL \n"); } /*stampa di una lista (versione iterativa)*/ void stampalista_iter (L_PTR L1) { while (L1 !=NULL) { printf("--> %d", L1->elem); L1=L1->next;} printf("-->NULL \n"); } Si scriva una procedura che data una lista Ne stampi gli elementi (iterativa) NULL3 7 54 2800570013006900 L 3 7 5 4 NULL
68
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Operazioni sulle liste Vedremo le seguenti operazioni – Verifica se la lista è vuota –Inserimento in testa ad una lista OK –Inserimento in una lista ordinata –Cancellazione di un elemento in una lista – Verifica se una lista è ordinata –Stampa di una lista OK –Somma degli elementi di una lista –Numero di occorrenze di un valore in una lista
69
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010
70
Esercizio -somma degli elementi di una lista /*calcola la somma degli elementi di una lista */ int sum_elementi(L_PTR L1) { int sum=0; while (L1 != NULL) {sum+=L1->elem;L1=L1->next;} return sum; } /*versione ricorsiva*/ int sum_elementi(L_PTR L1) { if (L1!=NULL) return ((L1->elem)+(sum_elementi(L1->next))); else return 0; } Si scriva una funzione Che dato una lista Calcoli la somma dei Suoi elementi ® Si scriva una funzione Che dato una lista Calcoli la somma dei Suoi elementi (iterativa) NULL3 7 54 2800570013006900 L La somma degli elemento di una lista è data dallelemento corrente più la somma degli altri elementi della lista OVVERO dallelemento corrente + il risultato della chiamata ricorsiva sul resto della lista 19
71
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Operazioni sulle liste Vedremo le seguenti operazioni – Verifica se la lista è vuota –Inserimento in testa ad una lista OK –Inserimento in una lista ordinata –Cancellazione di un elemento in una lista – Verifica se una lista è ordinata –Stampa di una lista OK –Somma degli elementi di una lista OK –Numero di occorrenze di un valore in una lista
72
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010Esercizio /*calcola il numero di occorrenze di un dato valore in una lista*/ int num_occorrenze(L_PTR L1, int val) { int occorrenze = 0; while (L1 !=NULL) { if (L1->elem == val) if (L1->elem == val) occorrenze++; occorrenze++; L1=L1->next; L1=L1->next;} return (occorrenze); } /*versione ricorsiva*/ int num_occorrenze (L_PTR L1, int val) { if (L1 == NULL) return 0; else return ((L1->elem == val)? (1+num_occorrenze(L1->next,val)):(num_occorrenze(L1->next,val))); } Si scriva una funzione che Data una lista ed un valore Calcoli il numero di Occorrenze del valore Nella lista ® Si scriva una funzione che Data una lista ed un valore Calcoli il numero di Occorrenze del valore Nella lista (iterativa) NULL3 7 54 2800570013006900 L Il numero di occorrenze di val in una lista è dato da 1+ il numero di occorrenze nel resto della lista SE lelemento corrente contiene il valore val Dal numero di occorrenze nel resto della lista se lelemento corrente NON contiene il valore val 1 val=7
73
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Operazioni sulle liste Vedremo le seguenti operazioni – Verifica se la lista è vuota –Inserimento in testa ad una lista OK –Inserimento in una lista ordinata –Cancellazione di un elemento in una lista – Verifica se una lista è ordinata –Stampa di una lista OK –Somma degli elementi di una lista OK –Numero di occorrenze di un valore in una lista OK –Verifica se un elemento compare nella lista
74
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010Esercizio int verifica_presenza (L_PTR L1, int val) { if (L1 == NULL) return 0; else return ((L1->elem==val)|| verifica_presenza(L1->next,val));} Si scriva una funzione Che data una lista ed Un valore verifichi Se il valore compare tra Gli elementi della lista NULL3 7 54 2800570013006900 L val compare in una lista se O lelemento corrente è pari a val OPPURE val occorre nel resto della lista Se la lista è vuota NON ha elementi quindi qualsiasi elemento non compare nella lista 0 val=6
75
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Operazioni sulle liste Vedremo el seguenti operazioni – Verifica se la lista è vuota –Inserimento in testa ad una lista OK –Inserimento in una lista ordinata –Cancellazione di un elemento in una lista – Verifica se una lista è ordinata –Stampa di una lista OK –Somma degli elementi di una lista OK –Numero di occorrenze di un valore in una lista OK –Verifica se un elemento compare nella lista OK
76
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010
77
Esercizio int verifica_ordinata (L_PTR L1) { L_PTR tempPtr; if ((L1 == NULL) || (L1->next == NULL)) return 1; else{tempPtr=L1; while (tempPtr->next !=NULL) { if (tempPtr->elem> tempPtr->next->elem) return 0; elsetempPtr=tempPtr->next;} return 1; }} Verifica che la lista sia ordinata in ordine crescente due elementi consecutivi non rispettano lordinamento Abbiamo considerato tutti gli elementi e sono ordinati in ordine crescente
78
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Esercizio (versione avanzata) /*verifica se la lista e' ordinata- E' ordinata se e' ordinata in ordine crescente o decrescente. Nel primo caso ord varra' 1 altrimenti 2. Alla prima chiamata ord sara' inizializzato a 0*/ int verifica_se_ordinata (L_PTR L1, int ord) { if ((L1 == NULL) || (L1->next == NULL)) return 1; switch (ord) { case 0: if (L1->elem == L1->next->elem) return (verifica_se_ordinata(L1->next,0)); return (verifica_se_ordinata(L1->next,0)); else if (L1->elem next->elem) else if (L1->elem next->elem) return (verifica_se_ordinata (L1->next, 1)); return (verifica_se_ordinata (L1->next, 1)); else return (verifica_se_ordinata(L1->next, 2)); else return (verifica_se_ordinata(L1->next, 2)); break; break; case 1: return ((L1->elem next->elem) && (verifica_se_ordinata (L1- >next, 1))); break; break; case 2:return ((L1->elem >= L1->next->elem) && (verifica_se_ordinata (L1- >next, 2))); break; break; default: break; }} Si scriva una funzione che, data una lista verifichi se e ordinata (in ordine crescente O decrescente) ®
79
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Operazioni sulle liste Vedremo le seguenti operazioni – Verifica se la lista è vuota –Inserimento in testa ad una lista OK –Inserimento in una lista ordinata –Cancellazione di un elemento in una lista – Verifica se una lista è ordinata OK –Stampa di una lista OK –Somma degli elementi di una lista OK –Numero di occorrenze di un valore in una lista OK –Verifica se un elemento compare nella lista OK
80
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Verifica se la lista è vuota int isempty (L_PTR L1) { return (L1==NULL); }
81
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Operazioni sulle liste Vedremo le seguenti operazioni – Verifica se la lista è vuota OK –Inserimento in testa ad una lista OK –Inserimento in una lista ordinata –Cancellazione di un elemento in una lista – Verifica se una lista è ordinata OK –Stampa di una lista OK –Somma degli elementi di una lista OK –Numero di occorrenze di un valore in una lista OK –Verifica se un elemento compare nella lista OK
82
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} Alloco memoria per il nuovo elemento. NULL val curr tempPtr prev
83
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL; curr=L ; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} NULL val curr tempPtr prev NULL 3 4 910 2800570013006900 L
84
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->elem)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} NULL 8 curr tempPtr prev NULL 3 4 910 2800570013006900 L se val=8
85
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} NULL 8 curr tempPtr prev NULL3 4 910 2800570013006900 L se val=8
86
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} NULL 8 curr tempPtr prev NULL3 4 910 2800570013006900 L se val=8 Si sfrutta il fatto che si valuta la condizione da sinistra a destra !!
87
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} NULL 8 curr tempPtr prev NULL3 4 910 2800570013006900 L
88
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} NULL 8 curr tempPtr prev NULL3 4 910 2800570013006900 L
89
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} 8 curr tempPtr prev NULL3 4 910 2800570013006900 L
90
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} Esco dalla funzione. Dealloco memoria per le var locali alla funzione 8 curr tempPtr prev NULL3 4 910 2800570013006900 L
91
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} Restituisco il valore di L che punta correttamente alla testa della nuova lista 8 NULL3 4 910 2800570013006900 L
92
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Ancora su inserimento ordinato Cosa sarebbe successo nel caso in cui val=2?
93
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->elem)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} Alloco memoria per il nuovo elemento. NULL 2 curr tempPtr prev
94
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL; curr=L ; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} NULL 2 curr tempPtr prev NULL 3 4 910 2800570013006900 L
95
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->elem)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} NULL 2 curr tempPtr prev NULL 3 4 910 2800570013006900 L se val=2
96
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} 2 curr tempPtr prev NULL3 4 910 2800570013006900 L se val=2 NULL
97
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} 2 curr tempPtr prev NULL3 4 910 2800570013006900 L Si rilascia la memoria Allocata per tempPtr curr, prev NULL
98
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} 2 NULL3 4 910 2800570013006900 L Nel main L=inserimento_ordinato(L,2); Il valore restituito dalla funzione è quello che era contenuto in tempPtr ovvero lindirizzo del nuovo primo elemento della lista
99
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Altro caso… Cosa succederebbe nel caso in cui val=12? (inserimento in fondo alla lista)
100
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} Alloco memoria per il nuovo elemento. NULL val curr tempPtr prev
101
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL; curr=L ; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} NULL val curr tempPtr prev NULL 3 4 910 2800570013006900 L
102
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} NULL 12 curr tempPtr prev NULL 3 4 910 2800570013006900 L se val=12
103
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} NULL 12 curr tempPtr prev NULL3 4 910 2800570013006900 L se val=12
104
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} NULL 12 curr tempPtr prev NULL3 4 910 2800570013006900 L se val=12
105
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} NULL 12 curr tempPtr prev NULL3 4 910 2800570013006900 L se val=12
106
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} NULL 12 curr tempPtr prev NULL3 4 910 2800570013006900 L se val=12 NULL
107
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} NULL 12 curr tempPtr prev NULL3 4 910 2800570013006900 L NULL
108
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} NULL 12 curr tempPtr prev 3 4 910 2800570013006900 L NULL
109
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} NULL 12 curr tempPtr prev 3 4 910 2800570013006900 L NULL
110
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} Esco dalla funzione. Dealloco memoria per le var locali alla funzione 12 curr tempPtr prev 3 4 910 2800570013006900 L NULL
111
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Inserimento in una lista ordinata L_PTR inserimento_ordinato (L_PTR L, int val) { L_PTR tempPtr, prev, curr; tempPtr=malloc(sizeof(struct nodo)); if (tempPtr!=NULL) { tempPtr->elem=val;tempPtr->next=NULL;prev=NULL;curr=L; while ((curr!=NULL) && (val >curr->val)){ prev=curr;curr=curr->next;} if (prev==NULL){ tempPtr->next=L; return tempPtr; }else{prev->next=tempPtr;tempPtr->next=curr; return L; }}else{ printf(impossibiel inserire nuovo elemento 1n); return L; }} 12 3 4 910 2800570013006900 L NULL Restituisco il valore di L che punta correttamente alla testa della nuova lista
112
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Altri esercizi Inserimento in coda alla lista (varie versioni) Inserimento in coda alla lista (varie versioni) Cancellazione di un elemento (ricorsiva e cancellazione di tutte le occorrenze) Data una lista la si inverta Data una lista si eleimini un elemento ogni val Data una lista si eliminino i valori pari contenuti nella lista
113
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010Esercizio /*prende un elemento e lo inserisce in coda alla lista*/ L_PTR inserisci_in_coda (L_PTR L1, int val) { L_PTR tempptr1, tempptr2; tempptr2=malloc(sizeof(L_ELEM)); tempptr2->elem = val; tempptr2->next=NULL; if (L1 == NULL) return tempptr2; return tempptr2;else{ tempptr1=L1; tempptr1=L1; while (tempptr1->next !=NULL) while (tempptr1->next !=NULL) tempptr1=tempptr1->next; tempptr1=tempptr1->next; tempptr1->next=tempptr2; tempptr1->next=tempptr2; return L1; return L1;}} Si scriva una funzione iterativa Che inserisca un elemento In coda alla lista
114
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Esercizio -bis void insertTAILlista(LISTA *L1,int val) { LISTA temp,temp1; if (*L1==NULL) {temp=malloc(sizeof(NODOLISTA));temp->elem=val;temp->next=NULL;*L1=temp;}else{temp1=*L1; while (temp1->next!=NULL) temp1=temp1->next;temp=malloc(sizeof(NODOLISTA));temp->elem=val;temp->next=NULL;temp1->next=temp;}} Si scriva una funzione iterativa Che inserisca un elemento In coda alla lista struct node { int elem; struct node *next; }; typedef struct node NODOLISTA; typedef NODOLISTA *LISTA;
115
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 struct node { int elem; struct node *next; }; typedef struct node NODOLISTA; typedef NODOLISTA *LISTA; Esercizio -bis (versione ricorsiva) void RinsertTAILlista(LISTA *L1,int val) { LISTA temp; if (*L1==NULL) {temp=malloc(sizeof(NODOLISTA));temp->next=NULL;temp->elem=val;*L1=temp;} else RinsertTAILlista (&((*L1)->next),val); } Si scriva una funzione Che inserisca un elemento in coda alla lista ®
116
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010
117
Operazioni sulle liste Vedremo le seguenti operazioni – Verifica se la lista è vuota OK –Inserimento in testa ad una lista OK –Inserimento in una lista ordinata –Cancellazione di un elemento in una lista – Verifica se una lista è ordinata OK –Stampa di una lista OK –Somma degli elementi di una lista OK –Numero di occorrenze di un valore in una lista OK –Verifica se un elemento compare nella lista OK
118
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cancellazione di un elemento dalla lista /*pre: la lista non è vuota*/ L_PTR cancella(L_PTR L, int val) { L_PTR prev,curr,tempPtr; if (val==L->elem){ tempPtr=L;L=L->next;free(tempPtr); return L; }else{prev=L;curr=L->next; while ((curr!=NULL) && (curr->elem !=val)){ prev=curr;curr=curr->next;} if (curr !=NULL){ tempPtr=curr;prev->next=curr->next;free(tempPtr); return L; } }} Cancella solo la prima occorrenza di val nella lista Per esercizio cercate di generalizzare facendo cancellare TUTTE le occorrenze di val nella lista 3 4 910 2800570013006900 L
119
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cancellazione di un elemento dalla lista /*pre: la lista non è vuota*/ L_PTR cancella(L_PTR L, int val) { L_PTR prev,curr,tempPtr; if (val==L->elem){ tempPtr=L;L=L->next;free(tempPtr); return L; }else{prev=L;curr=L->next; while ((curr!=NULL) && (curr->elem !=val)){ prev=curr;curr=curr->next;} if (curr !=NULL){ tempPtr=curr;prev->next=curr->next;free(tempPtr); return L; } }} Supponiamo di voler cancellare la prima occorrenza del valore 3 nella lista 3 4 910 2800570013006900 L curr tempPtr prev
120
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cancellazione di un elemento dalla lista /*pre: la lista non è vuota*/ L_PTR cancella(L_PTR L, int val) { L_PTR prev,curr,tempPtr; if (val==L->elem){ tempPtr=L;L=L->next;free(tempPtr); return L; }else{prev=L;curr=L->next; while ((curr!=NULL) && (curr->elem !=val)){ prev=curr;curr=curr->next;} if (curr !=NULL){ tempPtr=curr;prev->next=curr->next;free(tempPtr); return L; } }} Supponiamo di voler cancellare la prima occorrenza del valore 3 nella lista 3 4 910 2800570013006900 L curr tempPtr prev
121
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cancellazione di un elemento dalla lista /*pre: la lista non è vuota*/ L_PTR cancella(L_PTR L, int val) { L_PTR prev,curr,tempPtr; if (val==L->elem){ tempPtr=L;L=L->next;free(tempPtr); return L; }else{prev=L;curr=L->next; while ((curr!=NULL) && (curr->elem !=val)){ prev=curr;curr=curr->next;} if (curr !=NULL){ tempPtr=curr;prev->next=curr->next;free(tempPtr); return L; } }} Supponiamo di voler cancellare la prima occorrenza del valore 3 nella lista 3 4 910 2800570013006900 L curr tempPtr prev
122
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cancellazione di un elemento dalla lista /*pre: la lista non è vuota*/ L_PTR cancella(L_PTR L, int val) { L_PTR prev,curr,tempPtr; if (val==L->elem){ tempPtr=L;L=L->next;free(tempPtr); return L; }else{prev=L;curr=L->next; while ((curr!=NULL) && (curr->elem !=val)){ prev=curr;curr=curr->next;} if (curr !=NULL){ tempPtr=curr;prev->next=curr->next;free(tempPtr); return L; } }} Supponiamo di voler cancellare la prima occorrenza del valore 3 nella lista 3 4 910 2800570013006900 L curr tempPtr prev La memoria che era stata allocata per il primo elemento che conteneva il valore cancellato è deallocata
123
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cancellazione di un elemento dalla lista /*pre: la lista non è vuota*/ L_PTR cancella(L_PTR L, int val) { L_PTR prev,curr,tempPtr; if (val==L->elem){ tempPtr=L;L=L->next;free(tempPtr); return L; }else{prev=L;curr=L->next; while ((curr!=NULL) && (curr->elem !=val)){ prev=curr;curr=curr->next;} if (curr !=NULL){ tempPtr=curr;prev->next=curr->next;free(tempPtr); return L; } }} Supponiamo di voler cancellare la prima occorrenza del valore 3 nella lista 4 910 570013006900 L Viene restituito al chiamante L che punta Alla nuova testa della lista
124
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cosa succederebbe Se il valore da cancellare fosse 9..
125
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cancellazione di un elemento dalla lista /*pre: la lista non è vuota*/ L_PTR cancella(L_PTR L, int val) { L_PTR prev,curr,tempPtr; if (val==L->elem){ tempPtr=L;L=L->next;free(tempPtr); return L; }else{prev=L;curr=L->next; while ((curr!=NULL) && (curr->elem !=val)){ prev=curr;curr=curr->next;} if (curr !=NULL){ tempPtr=curr;prev->next=curr->next;free(tempPtr); return L; } }} Supponiamo di voler cancellare la prima occorrenza del valore 9 nella lista 3 4 910 2800570013006900 L curr tempPtr prev
126
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cancellazione di un elemento dalla lista /*pre: la lista non è vuota*/ L_PTR cancella(L_PTR L, int val) { L_PTR prev,curr,tempPtr; if (val==L->elem){ tempPtr=L;L=L->next;free(tempPtr); return L; }else{prev=L;curr=L->next; while ((curr!=NULL) && (curr->elem !=val)){ prev=curr;curr=curr->next;} if (curr !=NULL){ tempPtr=curr;prev->next=curr->next;free(tempPtr); return L; } }} Supponiamo di voler cancellare la prima occorrenza del valore 9 nella lista 3 4 910 2800570013006900 L curr tempPtr prev
127
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cancellazione di un elemento dalla lista /*pre: la lista non è vuota*/ L_PTR cancella(L_PTR L, int val) { L_PTR prev,curr,tempPtr; if (val==L->elem){ tempPtr=L;L=L->next;free(tempPtr); return L; }else{prev=L;curr=L->next; while ((curr!=NULL) && (curr->elem !=val)){ prev=curr;curr=curr->next;} if (curr !=NULL){ tempPtr=curr;prev->next=curr->next;free(tempPtr); return L; } }} Supponiamo di voler cancellare la prima occorrenza del valore 9 nella lista 3 4 910 2800570013006900 L curr tempPtr prev
128
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cancellazione di un elemento dalla lista /*pre: la lista non è vuota*/ L_PTR cancella(L_PTR L, int val) { L_PTR prev,curr,tempPtr; if (val==L->elem){ tempPtr=L;L=L->next;free(tempPtr); return L; }else{prev=L;curr=L->next; while ((curr!=NULL) && (curr->elem !=val)){ prev=curr;curr=curr->next;} if (curr !=NULL){ tempPtr=curr;prev->next=curr->next;free(tempPtr); return L; } }} Supponiamo di voler cancellare la prima occorrenza del valore 9 nella lista 3 4 910 2800570013006900 L curr tempPtr prev
129
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cancellazione di un elemento dalla lista /*pre: la lista non è vuota*/ L_PTR cancella(L_PTR L, int val) { L_PTR prev,curr,tempPtr; if (val==L->elem){ tempPtr=L;L=L->next;free(tempPtr); return L; }else{prev=L;curr=L->next; while ((curr!=NULL) && (curr->elem !=val)){ prev=curr;curr=curr->next;} if (curr !=NULL){ tempPtr=curr;prev->next=curr->next;free(tempPtr); return L; } }} Supponiamo di voler cancellare la prima occorrenza del valore 9 nella lista 3 4 910 2800570013006900 L curr tempPtr prev
130
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cancellazione di un elemento dalla lista /*pre: la lista non è vuota*/ L_PTR cancella(L_PTR L, int val) { L_PTR prev,curr,tempPtr; if (val==L->elem){ tempPtr=L;L=L->next;free(tempPtr); return L; }else{prev=L;curr=L->next; while ((curr!=NULL) && (curr->elem !=val)){ prev=curr;curr=curr->next;} if (curr !=NULL){ tempPtr=curr;prev->next=curr->next;free(tempPtr); return L; } }} Supponiamo di voler cancellare la prima occorrenza del valore 9 nella lista 3 4 910 2800570013006900 L curr tempPtr prev
131
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cancellazione di un elemento dalla lista /*pre: la lista non è vuota*/ L_PTR cancella(L_PTR L, int val) { L_PTR prev,curr,tempPtr; if (val==L->elem){ tempPtr=L;L=L->next;free(tempPtr); return L; }else{prev=L;curr=L->next; while ((curr!=NULL) && (curr->elem !=val)){ prev=curr;curr=curr->next;} if (curr !=NULL){ tempPtr=curr;prev->next=curr->next;free(tempPtr); return L; } }} Restituiamo L che è il puntatore alla testa della lista modificata 3 4 10 280057006900 L
132
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Ulteriore caso… Cosa succederebbe se volessimo cancellare 5 (5 non compare tra gli elementi della lista…) Fate da soli il caso in cui si cancella lultimo elemento della lista…
133
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cancellazione di un elemento dalla lista /*pre: la lista non è vuota*/ L_PTR cancella(L_PTR L, int val) { L_PTR prev,curr,tempPtr; if (val==L->elem){ tempPtr=L;L=L->next;free(tempPtr); return L; }else{prev=L;curr=L->next; while ((curr!=NULL) && (curr->elem !=val)){ prev=curr;curr=curr->next;} if (curr !=NULL){ tempPtr=curr;prev->next=curr->next;free(tempPtr); return L; } }} Supponiamo di voler cancellare la prima occorrenza del valore 5 nella lista 3 4 910 2800570013006900 L curr tempPtr prev
134
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cancellazione di un elemento dalla lista /*pre: la lista non è vuota*/ L_PTR cancella(L_PTR L, int val) { L_PTR prev,curr,tempPtr; if (val==L->elem){ tempPtr=L;L=L->next;free(tempPtr); return L; }else{prev=L;curr=L->next; while ((curr!=NULL) && (curr->elem !=val)){ prev=curr;curr=curr->next;} if (curr !=NULL){ tempPtr=curr;prev->next=curr->next;free(tempPtr); return L; } }} Supponiamo di voler cancellare la prima occorrenza del valore 5 nella lista 3 4 910 2800570013006900 L curr tempPtr prev
135
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cancellazione di un elemento dalla lista /*pre: la lista non è vuota*/ L_PTR cancella(L_PTR L, int val) { L_PTR prev,curr,tempPtr; if (val==L->elem){ tempPtr=L;L=L->next;free(tempPtr); return L; }else{prev=L;curr=L->next; while ((curr!=NULL) && (curr->elem !=val)){ prev=curr;curr=curr->next;} if (curr !=NULL){ tempPtr=curr;prev->next=curr->next;free(tempPtr); return L; } }} Supponiamo di voler cancellare la prima occorrenza del valore 5 nella lista 3 4 910 2800570013006900 L curr tempPtr prev
136
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cancellazione di un elemento dalla lista /*pre: la lista non è vuota*/ L_PTR cancella(L_PTR L, int val) { L_PTR prev,curr,tempPtr; if (val==L->elem){ tempPtr=L;L=L->next;free(tempPtr); return L; }else{prev=L;curr=L->next; while ((curr!=NULL) && (curr->elem !=val)){ prev=curr;curr=curr->next;} if (curr !=NULL){ tempPtr=curr;prev->next=curr->next;free(tempPtr); return L; } }} Supponiamo di voler cancellare la prima occorrenza del valore 5 nella lista 3 4 910 2800570013006900 L curr tempPtr prev
137
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cancellazione di un elemento dalla lista /*pre: la lista non è vuota*/ L_PTR cancella(L_PTR L, int val) { L_PTR prev,curr,tempPtr; if (val==L->elem){ tempPtr=L;L=L->next;free(tempPtr); return L; }else{prev=L;curr=L->next; while ((curr!=NULL) && (curr->elem !=val)){ prev=curr;curr=curr->next;} if (curr !=NULL){ tempPtr=curr;prev->next=curr->next;free(tempPtr); return L; } }} Supponiamo di voler cancellare la prima occorrenza del valore 5 nella lista 3 4 910 2800570013006900 L curr tempPtr prev NULL
138
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Cancellazione di un elemento dalla lista /*pre: la lista non è vuota*/ L_PTR cancella(L_PTR L, int val) { L_PTR prev,curr,tempPtr; if (val==L->elem){ tempPtr=L;L=L->next;free(tempPtr); return L; }else{prev=L;curr=L->next; while ((curr!=NULL) && (curr->elem !=val)){ prev=curr;curr=curr->next;} if (curr !=NULL){ tempPtr=curr;prev->next=curr->next;free(tempPtr); return L; } }} Supponiamo di voler cancellare la prima occorrenza del valore 5 nella lista In questo caso la lista non va modificata 3 4 910 2800570013006900 L curr tempPtr prev NULL
139
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Altri esercizi Cancellazione di tutte le occorrenze di un dato valore da una lista (ricorsiva)
140
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Esercizio void RdeleteELEMlista(L_PTR * L, int val) { L_PTR temp; if (*L==NULL) return; else if (((*L)->elem)==val) {temp=*L;*L=(*L)->next;free(temp);RdeleteELEMlista(L,val);} else RdeleteELEMlista (&((*L)->next),val); } Si scriva una funzione Ricorsiva che, data una lista elimini Le occorrenze di val nella lista struct node { int elem; struct node *next; }; typedef struct node NODOLISTA; typedef NODOLISTA *LISTA;
141
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Altri esercizi Data una lista la si inverta
142
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Esercizio (inversione lista) L_PTR Rinvertilista(L_PTR L) { L_PTR temp; if ((L==NULL) ||(L->next == NULL)) return L; else{ temp=Rinvertilista(L->next); temp=Rinvertilista(L->next); L->next->next=L; L->next->next=L; L->next=NULL; L->next=NULL; return temp; return temp;}} Si scriva una funzione che, data una lista La inverta ®
Presentazioni simili
© 2024 SlidePlayer.it Inc.
All rights reserved.