Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 Corso di Programmazione 1 a.a.2007/2008 Prof.ssa Chiara Petrioli Corso di Laurea in Informatica Università degli Studi La Sapienza (lezioni 16-19) Strutture, Unioni e Liste
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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)
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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;
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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)
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 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.
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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).
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008
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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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; };
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008Soluzione 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008typedef 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 !
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008Esempio 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.
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008Codice #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 *);
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008Codicemain(){ 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008Codice 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;}}
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 Codice void deal (Card *wDeck) { int i; for (i=0;i<=51;i++) printf(%s of %s \n, wDeck[i].face, wDeck[i].suit); }
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008
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)
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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)
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008Liste 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008Esempio 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008Esempio struct node *Lista; Un elemento può contenere dati di ogni tipo (incluse altre struct) Gli elementi vengono aggiunti e cancellati dinamicamente. 152 NULL
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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.
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 Esercizi su liste struct nodo { int elem; struct nodo * next; }; typedef struct nodo L_ELEM; typedef struct nodo * L_PTR;
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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; }
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 Cosa succede in memoria… L_PTR inserisci_in_testa(L_PTR L1, int val) {………….} NULL L 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 Cosa succede in memoria… L_PTR inserisci_in_testa(L_PTR L1, int val) {………….} NULL L 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 Cosa succede in memoria… L_PTR inserisci_in_testa(L_PTR L1, int val) {………….} NULL L 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 L In val viene copiato il valore di v
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L L1 val 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L L1 val 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L 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 val
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 Cosa succede in memoria… L2=inserisci_in_testa(L2,v)} NULL L L19100 Il valore ritornato e assegnato a L2 che ora punta (correttamente) al nuovo primo elemento della lista 9100 { Nuovo elemento temp_ptr val
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 Cosa succede in memoria… Void inserisci_in_testa(L_PTR L1, int val) {………….} NULL L 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 Cosa succede in memoria… void inserisci_in_testa(L_PTR L1, int val) void inserisci_in_testa(L_PTR L1, int val){………….} NULL L 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 Cosa succede in memoria… Void inserisci_in_testa(L_PTR L1, int val) {………….} NULL L 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 L In val viene copiato il valore di v
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L L1 val 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L L1 val 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L L19100 L1 viene aggiornato con quello che e lindirizzo della locazione di memoria del nuovo primo elemento della lista. Si esce dalla funzione { Nuovo elemento temp_ptr val
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 Cosa succede in memoria… NULL L L ) La memoria per L1, temp_ptr e val viene deallocata alluscita dalla funzione 9100 { Nuovo elemento temp_ptr 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!!!
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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)
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 Cosa succede in memoria… void inserisci_in_testa(L_PTR *LISTAPTR, int val) {………….} NULL L 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 Cosa succede in memoria… void inserisci_in_testa(L_PTR* LISTAPTR, int val) void inserisci_in_testa(L_PTR* LISTAPTR, int val){………….} NULL L 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 Cosa succede in memoria… Void inserisci_in_testa(L_PTR* LISTAPTR, int val) {………….} NULL LISTAPTR Vediamo ora cosa succede se dal main viene invocato: inserisci_in_testa(&L2,v) dove v vale 5…. val 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 L
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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; } NULL 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 temp_ptr L
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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; } NULL *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 temp_ptr L
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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) NULL L NULL
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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) NULL 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008
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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008Esercizio /*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) NULL 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008Esercizio 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 NULL 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 ® E considerando diversi Possibili tipi di Ordinamneto specificati Da input
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 Verifica se la lista è vuota int isempty (L_PTR L1) { return (L1==NULL); }
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L se val=8
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 NULL L se val=8
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 NULL L se val=8 Si sfrutta il fatto che si valuta la condizione da sinistra a destra !!
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 NULL L
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 NULL L
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 NULL L
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 NULL L
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 NULL L
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 Ancora su inserimento ordinato Cosa sarebbe successo nel caso in cui val=2?
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L se val=2
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 NULL L se val=2 NULL
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 NULL L Si rilascia la memoria Allocata per tempPtr curr, prev NULL
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 NULL 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 Altro caso… Cosa succederebbe nel caso in cui val=12? (inserimento in fondo alla lista)
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L se val=12
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L se val=12
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L se val=12
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L se val=12
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L se val=12 NULL
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L NULL
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L NULL
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L NULL
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L NULL
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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; }} L NULL Restituisco il valore di L che punta correttamente alla testa della nuova lista
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008
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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L curr tempPtr prev
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L curr tempPtr prev
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L curr tempPtr prev
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L curr tempPtr prev La memoria che era stata allocata per il primo elemento che conteneva il valore cancellato è deallocata
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L Viene restituito al chiamante L che punta Alla nuova testa della lista
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 Cosa succederebbe Se il valore da cancellare fosse 9..
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L curr tempPtr prev
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L curr tempPtr prev
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L curr tempPtr prev
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L curr tempPtr prev
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L curr tempPtr prev
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L curr tempPtr prev
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 Ulteriore caso… Cosa succederebbe se volessimo calcellare 5 (5 non compare tra gli elementi della lista…) Fate da soli il caso in cui si cancella lultimo elemento della lista…
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L curr tempPtr prev
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L curr tempPtr prev
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L curr tempPtr prev
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L curr tempPtr prev
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L curr tempPtr prev NULL
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 L curr tempPtr prev NULL
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008Esercizio /*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
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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;
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 ®
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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;
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 Quello che segue e le correzioni degli HW a gennaio?
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 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 ®
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008Esercizio Si scriva una funzione Ricorsiva che, data una lista elimini Un elemento ogni val struct node { int elem; struct node *next; }; typedef struct node NODOLISTA; typedef NODOLISTA *LISTA; LISTA eliminaognik (LISTA l1, int k, int val) { LISTA temp; if (l1==NULL) return l1; else if (k==0) {temp=l1;l1=l1->next; free (temp); return eliminaognik(l1,val,val); }else{l1->next=eliminaognik(l1->next,k-1,val); return l1; }}
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008Esercizio void eliminaognikpuntpunt (LISTA *l1, int k, int val) { LISTA temp; if (*l1==NULL) return; else if (k==0) {temp=*l1;*l1=(*l1)->next; free (temp); eliminaognikpuntpunt(l1,val,val);return;}else{eliminaognikpuntpunt(&((*l1)->next),k-1,val);return;}} Si scriva una funzione Ricorsiva che, data una lista elimini Un elemento ogni val struct node { int elem; struct node *next; }; typedef struct node NODOLISTA; typedef NODOLISTA *LISTA;
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008Esercizio void eliminapari(LISTA *l1) { LISTA temp; if (*l1==NULL) return; else if ((*l1)->elem %2) {eliminapari(&(*l1)->next);return;}else{temp=*l1;*l1=(*l1)->next;free(temp);eliminapari(l1);return;}} Si scriva una funzione Ricorsiva che, data una lista elimini Gli elementi contenenti Valori pari
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008Unioni Una unione, come una struttura, è un tipo di dato derivato i cui membri condividono lo stesso spazio di memoria In varie situazioni in un programma alcune variabili potrebbero essere irrilevanti mentre altre no. Per questo motivo le unioni consentono di specificare un insieme di membri delunione (che possono essere di tipo diverso), uno solo dei quali sarà attivo in un determinato momento. Allocare memoria ad una unione significa allocare memoria sufficiente a contenere il membro più grande E responsabilità del programmatore far riferimento al membro e tipo di dato corretto (attivo)
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008UnioniDichiarazioni union number { int x; float y; };Inizializzazioni union number value ={10}; /*una inizializzazione di questo tipo si può fare solo inizializzando al primo tipo dellunione. Altrimenti occorre inizializzare il valore del membro esplicitamente*/ Operazioni su union – assegnare ununione ad unaltra dello stesso tipo, rilevarne lindirizzo, accedere ai membri dellunione (con gli stessi operatori usati per le struct) Uno solo dei due attivo in un determinato momento
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 Unioni-esempio Vogliamo mantenere informazioni sui dipendenti di una azienda Lavoratori co-co-pro hanno informazioni da memorizzare per il calcolo dello stipendio (la quantità di soldi che vanno alla gestione separata dellINPS, durata del contratto, periodicità di pagamento,...) Lavoratori a tempo indeterminato hanno informazioni diverse da memorizzare (classe stipendiale, previdenza INPS, TFR, tredicesima, quattordicesima,....) Si potrebbe usare una union. –In base ad un campo flag si individua a che tipo di lavoratore si fa riferimento (per rendere edotto il programma sui campi che si troverà davanti) –La union consente di far sì che un elemento (ad esempio la entry per Guido Rossi) abbia associato i campi opportuni (a seconda che sia un lavoratore co-co-pro o dipendente) –Usando la union si può così risparmiare un po in termini di memoria