Le strutture dati elementari (II parte) Gianpiero Cabodi Dip. Automatica e Informatica Politecnico di Torino Nodo /* tipo per il dato in lista */ typedef ... Item; /* nodo contenente dato e link */ typedef struct node *link; struct node { Item item; link next; } A.A. 2006/2007 03 Le strutture dati elementari (II parte) 2 Operazioni link x; ... Allocazione nodo x x = malloc(sizeof *x); oppure x = malloc(sizeof(struct node)); item next x A.A. 2006/2007 03 Le strutture dati elementari (II parte) 3 link x, t; ... Inserire nodo t dopo x in lista concatenata semplice t t->next x x->next A.A. 2006/2007 03 Le strutture dati elementari (II parte) 4 t->next = x->next; t t->next x x->next A.A. 2006/2007 03 Le strutture dati elementari (II parte) 5 x->next = t; t->next t x x->next A.A. 2006/2007 03 Le strutture dati elementari (II parte) 6 link x, t; ... Cancellare il nodo dopo x in lista concatenata semplice x x->next t A.A. 2006/2007 t->next ossia x->next->next 03 Le strutture dati elementari (II parte) 7 x->next = x->next->next; x->next x t x->next->next; A.A. 2006/2007 03 Le strutture dati elementari (II parte) 8 link x, t; ... Inserire nodo t dopo x in lista concatenata doppia t x x->next A.A. 2006/2007 03 Le strutture dati elementari (II parte) 9 t->next = x->next; t t->next x x->next A.A. 2006/2007 03 Le strutture dati elementari (II parte) 10 x->next->prev = t; t t->next x->next->prev x x->next A.A. 2006/2007 03 Le strutture dati elementari (II parte) 11 x->next = t; t x->next->prev x x->next t->next A.A. 2006/2007 03 Le strutture dati elementari (II parte) 12 t->prev = x; t->prev t x->next->prev x x->next t->next A.A. 2006/2007 03 Le strutture dati elementari (II parte) 13 link t; ... Cancellare nodo t in lista concatenata doppia t->prev t t->next A.A. 2006/2007 03 Le strutture dati elementari (II parte) … 14 t->next->prev = t->prev; t->next->prev t->prev t t->next A.A. 2006/2007 03 Le strutture dati elementari (II parte) … 15 t->prev->next = t->next; t->next->prev t->prev t->prev->next t A.A. 2006/2007 t->next 03 Le strutture dati elementari (II parte) … 16 Il problema di Giuseppe Flavio N oggetti sono disposti in cerchio Si elimina un oggetto ogni M e si richiude il cerchio Quale oggetto rimane per ultimo? Con quale ordine si eliminano gli oggetti? A.A. 2006/2007 03 Le strutture dati elementari (II parte) 17 Implementazione 1 2 3 4 5 6 7 8 9 Lista circolare ogni oggetto connesso a quello immediatamente a SX i = i-esimo oggetto creazione della lista di N oggetti per inserzione partendo da 1, contare M-1 oggetti connettere l’M-1-esimo oggetto con l’M+1esimo, saltando l’M-esimo terminazione: 1 solo oggetto rimanente. A.A. 2006/2007 03 Le strutture dati elementari (II parte) 18 Inversione di lista r: puntatore alla porzione di lista già invertita (ultimo nodo già sistemato) y: puntatore alla porzione di lista da invertire (primo nodo ancora da sistemare) t: puntatore al nodo successivo al primo nodo ancora da sistemare (puntato da y) r y t A.A. 2006/2007 03 Le strutture dati elementari (II parte) 19 Operazioni: cambiare il link di y in modo che punti a r avanzamento: spostiamo r su y e y su t r y t A.A. 2006/2007 03 Le strutture dati elementari (II parte) 20 Inizialmente: y = x (la lista è ancora tutta da invertire) r = NULL (la lista già invertita è vuota) condizione di loop: esiste ancora una porzione da invertire y != NULL A.A. 2006/2007 03 Le strutture dati elementari (II parte) 21 Insertion sort su lista Input: lista non ordinata contenente N numeri casuali Output: lista ordinata ottenuta mediante insertion sort Lista: con nodo fittizio in testa (head node), non contiene dato, solo link al primo nodo significativo della lista A.A. 2006/2007 03 Le strutture dati elementari (II parte) 22 Rappresentazioni convenzionali A.A. 2006/2007 lista circolare mai vuota puntatore in testa, coda a NULL nodo fittizio in testa, coda a NULL nodi fittizi in testa e in coda. 03 Le strutture dati elementari (II parte) 23 Lista circolare, mai vuota primo inserimento inserisci t dopo x cancella dopo x ciclo di attraversamento testa se un solo elemento A.A. 2006/2007 head->next = head t->next = x->next; x->next = t x->next = x->next->next t = head do { … t = t->next; } while (t != head); if (head->next == head) 03 Le strutture dati elementari (II parte) 24 Puntatore in testa, coda a NULL inizializza inserisci t dopo x cancella dopo x ciclo di attraversamento testa se vuota A.A. 2006/2007 head = NULL if (head == NULL) {head = t;head->next = NULL;} else {t->next = x->next; x->next = t;} t = x->next; x->next = t->next; for (t = head; t != NULL; t = t->next ) if (head == NULL) 03 Le strutture dati elementari (II parte) 25 Nodo fittizio in testa, coda vuota inizializza head = malloc(sizeof *head); head->next = NULL; inserisci t dopo x t->next = x->next; x->next = t; cancella dopo x t = x->next; x->next = t->next; ciclo di for (t = head->next;t != NULL; attraversamento t = t->next ) testa se vuota if (head->next == NULL) A.A. 2006/2007 03 Le strutture dati elementari (II parte) 26 Nodi fittizi in testa e in coda inizializza head = malloc(sizeof *head); z = malloc(sizeof *z); head->next = z; z->next = z; inserisci t dopo x t->next = x->next; x->next = t; cancella dopo x x->next = x->next->next; ciclo di for (t = head->next; t != z; attraversamento t = t->next; ) testa se vuota if (head->next == z) A.A. 2006/2007 03 Le strutture dati elementari (II parte) 27 Interfaccia per liste Interfaccia Implementazione Client (Giuseppe Flavio) A.A. 2006/2007 03 Le strutture dati elementari (II parte) 28 Stringhe Importanza Definizione Implementazione con array Funzioni di libreria Stringhe e allocazione di memoria A.A. 2006/2007 03 Le strutture dati elementari (II parte) 29 Operazioni su stringhe (con array e puntatori) strlen(a): calcolo lunghezza for (i=0; a[i]!=’\0’; i++); return i; b=a; while(*b++); return b-a-1; strcpy(a,b): copia for (i=0; (a[i]=b[i])!=’\0’; i++); while(*a++=*b++); Nota: siccome il codice ASCII di ’\0’ è 0, spesso si usa direttamente 0 come terminatore di stringa A.A. 2006/2007 03 Le strutture dati elementari (II parte) 30 strcmp(a,b): confronta for (i=0; a[i]==b[i]; i++) if (a[i]==0) return 0; return a[i]-b[i]; while(*a++ == *b++) if (*(a-1) == 0) return 0; return *(a-1) - *(b-1); A.A. 2006/2007 03 Le strutture dati elementari (II parte) 31 Confronto tra puntatori if (a==b) e if (strcmp(a,b)==0) hanno due significati diversi: confronto tra due puntatori a stringhe confronto tra i contenuti di due stringhe Ovviamente (a==b)(puntatori coincidenti) implica contenuti identici, ma il viceversa è falso. A.A. 2006/2007 03 Le strutture dati elementari (II parte) 32 Ricerca su stringhe Problema: trovare tutte le occorrenze di una sottostringa p in una stringa a Soluzione: doppia iterazione annidata per ogni carattere a[i] di a z verifica se a[i] è inizio di una sottostringa uguale a p A.A. 2006/2007 03 Le strutture dati elementari (II parte) 33 Stringhe e allocazione di memoria Problema le stringhe hanno dimensione variabile. Prima di effettuare operazioni che costruiscono (es. strcpy) o allungano (es. strcat) stringhe, occorre assicurarsi che ci sia memoria allocata sufficiente A.A. 2006/2007 03 Le strutture dati elementari (II parte) 34 Soluzione Uso di malloc e free È necessario controllare la dimensione di un array prima di generarvi una stringa. Eventualmente riallocare. Tale gestione può risultare poco trasparente. A.A. 2006/2007 03 Le strutture dati elementari (II parte) 35