La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

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.

Presentazioni simili


Presentazione sul tema: "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."— Transcript della presentazione:

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 ®


Scaricare ppt "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."

Presentazioni simili


Annunci Google