/* questo file contiene alcune funzioni C per la gestione e manipolazione di linked list. L' implementazione delle function di manipolazione qui presentata e' solo una tra molte alternative. Viene fornita solo come esempio, senza pretesa di costituire la migliore soluzione. Non tutte le function sono effettivamente usate nel programma di prova. */ #define MAXC 40 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct nodo { char nome[MAXC]; struct nodo *successivo; } nodo; nodo *crea_nodo( void ) /* alloca memoria per un nuovo elemento ritornando un puntatore a questo spazio */ /* N.B. la creazione di un nuovo elemento NON lo inserisce nella lista: * nessun elemento punta ancora al nuovo e questo non punta a nessuno * (p->successivo punta a NULL) */ { nodo *nuovo_nodo; nuovo_nodo = malloc(sizeof(nodo) ); if ( nuovo_nodo == NULL ) { printf( "crea_nodo: allocazione di memoria fallita \n"); exit(1); } nuovo_nodo->successivo = NULL; return nuovo_nodo; } void aggiungi_nodo( nodo *nuovo_nodo , nodo **inizio) /* questa function aggiunge un elemento del tipo nodo in fondo alla lista * di primo elemento "inizio" * il parametro inizio deve essere di tipo puntatore a puntatore a nodo * per consentire alla function di modificare il parametro. */ { nodo *nodo_corrente; if ( *inizio == NULL) { *inizio = nuovo_nodo; return; } for( nodo_corrente = *inizio ; nodo_corrente->successivo != NULL ; nodo_corrente = nodo_corrente->successivo) ; // con questo for arriviamo all' ultimo nodo nodo_corrente->successivo = nuovo_nodo; return; } void inserisci_dopo(nodo *q, nodo *p) /* inserisce il nodo p dopo il nodo q */ { if ( p == NULL || q == NULL || p==q || q->successivo == p ) // per quanto riguarda le ultime due condizioni, sarebbe probabilmente meglio // ometterle dalla function in quanto non esaustive delle possibili situazioni // non valide in cui si tenti di inserire un elemento gia' presente nella // lista { printf("inserisci_dopo : inserzione non valida\n"); return; } p->successivo = q->successivo; q->successivo = p; return; } void elimina(nodo **eliminando, nodo **inizio) { nodo *p; if (*eliminando == *inizio) { if((*inizio)->successivo != NULL) *inizio = (*eliminando)->successivo; else *inizio=NULL; } else { for(p=*inizio; (p!= NULL) && (p->successivo !=*eliminando);p = p->successivo) if ( p == NULL) { printf("elimina: Errore: non c'e' l' elemento cercato " "nella lista \n"); return; } p->successivo = p->successivo->successivo; } free(*eliminando); *eliminando=NULL; } void scrivi_lista(nodo *inizio) { nodo *p; int count=0; if(inizio == NULL) printf("lista vuota\n"); else { p=inizio; do{count++; printf("%s\n",p->nome); p= p->successivo; } while(p != NULL); } printf("%d elementi\n",count); return; } nodo *trova_nome( char *nome , nodo *inizio) { nodo *p; p=inizio; do{ if(strcmp(nome,p->nome)==0) return p; }while((p=p->successivo) != NULL); return NULL; } int main(void) { char ans, buffer[80]; nodo *inizio=NULL; /* "inizio" e' il puntatore all' inizio della lista inizializzato a NULL */ nodo *p; int non_trovato; p=inizio; while(1) { printf(" new element ? (y/n) "); fgets(buffer,80,stdin); sscanf(buffer,"%c",&ans); if(ans == 'n') break; p=crea_nodo(); fgets(buffer,80,stdin); sscanf(buffer,"%80s",p->nome); aggiungi_nodo(p,&inizio); } do{ scrivi_lista(inizio); printf(" quale vuoi eliminare ? "); scanf("%79s",buffer); if((p=trova_nome(buffer,inizio)) != NULL) { printf("Trovato ! : %s \n",p->nome); non_trovato=0; elimina(&p,&inizio); scrivi_lista(inizio); } else { printf("Elemento non trovato. Riprova\n"); non_trovato=1; } } while(non_trovato); return 0; }