APPUNTI SUL LINGUAGGIO C Corso di Algoritmi e Strutture Dati APPUNTI SUL LINGUAGGIO C Liste Concatenate
Tipi di dato Struct (record) Puntatori Liste concatenate
Le Liste Concatenate Una lista concatenata è una collezione lineare di strutture connesse da puntatori, detti link (anelli o collegamenti), da cui il termine concatenata. Elemento Elemento Elemento
Le Liste Concatenate I nodi di una lista sono strutture ricorsive: una struttura contenente un membro di tipo puntatore, che fa riferimento a una struttura dello stesso tipo di quella in cui è contenuto. Elemento
Le Liste Concatenate Ci saranno sue nodi particolari: un puntatore al primo elemento e l’ultimo nodo punterà a NULL. Elemento
Le Liste Concatenate Ci saranno sue nodi particolari: un puntatore al primo elemento e l’ultimo nodo punterà a NULL. NULL Elemento
Inserimento di un nuovo nodo Cancellazione di un nodo esistente Liste concatenate Operazioni fondamentali: Inserimento di un nuovo nodo Cancellazione di un nodo esistente Ricerca/Aggiornamento di un nodo esistente
Lista semplicemente concatenata Un elemento x di una lista è un oggetto con almeno due campi info[x] campo chiave next[x] puntatore al successore dell’oggetto nella lista Una lista L è un oggetto con un campo: head[L] puntatore al primo elemento x della lista Lista vuota: head[L] = NIL head[L] NIL
Liste semplicemente concatenate in C // definizione della struttura nodo typedef struct elem{ int info; // <tipo> <valore del nodo>; struct elem* next; } elist; // definizione del puntatore ai nodi della lista typedef elist* plist;
Le Liste semplicemente Concatenate info plist info
Lista come parametro di una funzione Passare una lista come parametro significa passare il puntatore al primo nodo. Nel caso di inserimento e cancellazione, vogliamo ottenere un side effect sulla lista dopo la chiamata della funzione l
Lista come parametro di una funzione Ricordiamo che i parametri di una funzione in C vengono catturati per valore <tipo> funzione(plist l) l
La funzione ritorna un puntatore come risultato plist funzione(plist l) l // nel codice principale … l = funzione(l);
Passiamo per riferimento il puntatore void funzione(plist* l) l // nel codice principale … funzione(l);
Inserimento di un nuovo nodo: in Testa void funzione(plist* l, elemento el) l el temp INS-Testa(L,x) next[x] <- head[L] head[L] <- x
Inserimento di un nuovo nodo: in Testa // funzione per inserire in testa ad una lista un nuovo nodo void inserisciInTesta(plist* l, int n){ plist temp = (plist)malloc(sizeof(elist)); temp->info = n; temp->next = *l; *l = temp; }
Inserimento di un nuovo nodo: in Coda void funzione(plist* l, elemento el) l el Nil temp
Inserimento di un nuovo nodo: in Coda NULL(L) return (head[L] = NIL) INS-Coda(L,x) if NULL(L) then head(L) <- x else y <- head(L) while next(y) ≠ NIL do y <- next(y) next(y) <- x next(x) <- NIL
Inserimento di un nuovo nodo: in Coda //funzione per inserire in coda ad una lista un nuovo nodo void inserisciInCoda(plist* l, int n){ plist temp = (plist)malloc(sizeof(elist)); temp->info = n; temp->next = NULL; if (*l == NULL) *l = temp; else { plist temp2 = *l; while (temp2->next != NULL) temp2 = temp2->next; temp2->next=temp; }
Inserimento di un nuovo nodo: in una posizione precisa void funzione(plist* l, elemento el, int pos) prev cur l el temp
Inserimento di un nuovo nodo: in una posizione precisa Scrivere prima una funzione che calcola la lunghezza della lista Fare una casistica per valutare pos (e quindi ad esempio utilizzare gli inserimenti visti prima per la prima e l’ultima posizione) Quindi utilizzare prev e cur per la posizione i-esima LUNG(L) x <- head(L) cont <- 0 while x ≠ NIL do x = next(x) cont <- cont + 1 return cont
Inserimento di un nuovo nodo: in una posizione precisa // funzione per calcolare il numero di nodi di una lista int lungLista(plist l){ int cont = 0; while (l != NULL) { cont++; l = l->next; } return cont;
Inserimento di un nuovo nodo: in una posizione precisa INS-Pos(L,x,pos) if LUNG(L) < pos then INS-Coda(L,x) else switch pos case 0: error “posizione non valida" case 1: INS-Testa(L,x) default: prev <- head(L) cur <- next(prev) while pos > 2 do prev <- cur; cur <- next(cur) pos <- pos - 1 next(prev) <- x next(x) <- cur
Inserimento di un nuovo nodo: in una posizione precisa // funzione per inserire in un data posizione della lista un nuovo nodo void inserisciInPos(plist *l, int n, int pos) { plist prev,cur; plist temp = (plist)malloc(sizeof(elist)); temp->info = n; temp->next = NULL; int ln = lungLista(*l); if (ln<pos) inserisciInCoda(l,n); else
Inserimento di un nuovo nodo: in una posizione precisa switch (pos) { case 0: printf("bisogna indicare una posizione positiva maggiore di zero\n"); break; case 1: inserisciInTesta(l,n); break; default: prev = *l; cur = prev->next; while (pos>2) { prev = cur; cur = cur->next; pos--; } prev->next = temp; temp->next = cur;
Inserimento di un nuovo nodo: in una posizione precisa void funzione2(plist* l, elemento el, int pos) prev l el temp
Inserimento di un nuovo nodo: in una posizione precisa switch (pos) { case 0: printf("bisogna indicare una posizione positiva maggiore di zero\n"); break; case 1: inserisciInTesta(l,n); break; default: prev = *l; while (pos>2) { prev = prev->next; pos--; } temp->next = prev->next; prev->next = temp;
Cancellazione di un nodo: in Testa void funzione(plist* l) l temp CANC-Testa(L) if not NULL(L) then head(L) <- next(head(L)) else error “la lista è vuota”
Cancellazione di un nodo: in Testa // funzione per cancellare in una lista il nodo in testa void cancellaInTesta(plist* l){ if (*l != NULL) { plist temp = *l; *l = temp->next; free(temp); } else printf("La lista e' vuota\n");
Cancellazione di un nodo: in Coda void funzione(plist* l) l
Cancellazione di un nodo: in Coda CANC-Coda(L) switch LUNG(L) case 0: error “la lista è vuota” case 1: head(L) <- NIL default: prev <- head(L) cur <- next(prev) while next(cur) ≠ NIL do prev <- cur cur <- next(cur) next(prev) <- NIL
Cancellazione di un nodo: in Coda // funzione per cancellare in una lista il nodo in coda void cancellaInCoda(plist* l){ plist prev,cur; switch(lungLista(*l)) { case 0: printf("La lista e' vuota\n"); break; case 1: free(*l); break; default: prev = *l; cur=prev->next; while (cur->next != NULL){ prev = cur; cur = cur->next; } free(cur); prev->next=NULL;
Cancellazione di un nodo: in una posizione precisa void funzione(plist* l, int pos) prev cur l
Cancellazione di un nodo: in una posizione precisa CANC-Pos(L,pos) ln = LUNG(L) if ln < pos error “posizione non valida” else switch pos case 0: error “posizione non valida” case 1: CANC-Testa(L) default: prev <- head(L) cur <- next(prev) while pos > 2 do prev <- cur cur <- next(cur) pos = pos - 1 next(prev) <- next(cur)
Cancellazione di un nodo: in una posizione precisa // funzione per cancellare inun alista un nodo in una data posizione void cancellaInPos(plist* l, int pos){ plist prev,cur; int ln = lungLista(*l); if (ln<pos) printf("La lunghezza della lista e' minore della posizione fornita\n"); else switch(pos) { case 0: printf("Hai fornito una posizione non valida\n"); break; case 1: cancellaInTesta(l); break; default: prev = *l; cur=prev->next; while (pos>2){ prev = cur; cur = cur->next; pos--; } prev->next=cur->next; free(cur);
Ricerca di un nodo in una lista void funzione(plist l, valore x) l x SEARCH(L,k) if NULL(L) then return NIL else x <- head(L) while x ≠ NIL and info(x) ≠ k do x <- NEXT(x) return x
Ricerca di un nodo in una lista // funzione per cercare in una lista un nodo int cerca(plist l, int n){ int test = 0; while ((l!=NULL)&&(!test)) if (l->info == n) test = 1; else l = l->next; return test; }
Stampa dei campi chiave di una lista void stampa(plist l) l
Stampa dei campi chiave di una lista void stampa(plist l) { printf("( "); while (l) { printf("["); printf("%d",l->info); printf("] "); l = l->next; } printf(")\n");
Esercizio Data una lista L i cui nodi contengono valori interi, scrivere le seguenti procedure (pseudo-codice e implementazione in C): CANC-Val(L,x) che cancella nella lista L i nodi con valore x CONT-Val(L,x) che conta in L quanti nodi hanno valore x INS-Val(L,x,y) che inserisce in L un nodo con valore x dopo il nodo esistente in L con valore y (se il nodo con valore y non esiste allora sarà fatto un inserimento in coda)
APPUNTI SUL LINGUAGGIO C Corso di Algoritmi e strutture Dati APPUNTI SUL LINGUAGGIO C Liste Concatenate FINE