PDA

Visualizza la versione completa : [C] Eliminare nodo da una lista


goatboy
14-05-2012, 10:41
Salve a tutti. Sto scrivendo un programma di riepilogo sulle liste (in vista dell'esame :fighet: ). Ho problemi però per la funzione di eliminazione di un nodo. Io passo alla funzione il nome che voglio eliminare. Scorro la lista e man mano con la strcmp verifico se il nome passato è uguale al nome contenuto nella struct TNode. Nel caso strcmp==1, dealloco il nodo.
Non mi da errori, però non cancella niente. Non capisco :confused:

Chiamata nel main:


case 2:
if(lista==NULL){
printf("La lista e' vuota.\n");
}else{
printf("Inserisci il dato del nodo da eliminare: ");
scanf("%s", nome);
lista=Ricerca_Nodo_Da_Eliminare(lista, nome);
printf("Lista aggiornata:\n");
Stampa_Lista(lista);
}
break;


Funzione RICERCA_NODO_DA_ELIMINARE:


TList Ricerca_Nodo_Da_Eliminare(TList lista, char nome[]){
TNode *curr=lista;
while(curr!=NULL){
if(strcmp(nome, curr->info.nome)==1){
Elimina_Nodo(curr);
}
curr=curr->next;
}
return lista;
}


Funzione di DEALLOCAZIONE:


void Elimina_Nodo(TNode *nodo){
free(nodo);
}

Alex'87
14-05-2012, 10:45
Originariamente inviato da goatboy
Salve a tutti. Sto scrivendo un programma di riepilogo sulle liste (in vista dell'esame :fighet: ). Ho problemi però per la funzione di eliminazione di un nodo. Io passo alla funzione il nome che voglio eliminare. Scorro la lista e man mano con la strcmp verifico se il nome passato è uguale al nome contenuto nella struct TNode. Nel caso strcmp==1, dealloco il nodo.
Non mi da errori, però non cancella niente. Non capisco :confused:

strcmp restituisce 0 se le stringhe sono uguali, < 0 se la prima viene prima della seconda, > 0 viceversa.

goatboy
14-05-2012, 10:52
Originariamente inviato da Alex'87
strcmp restituisce 0 se le stringhe sono uguali, < 0 se la prima viene prima della seconda, > 0 viceversa.
Non funziona lo stesso. Quando vado a ristampare la lista, mi ristampa tutti i nominativi.

Andrea Simonassi
14-05-2012, 11:54
non basta deallocare, devi anche impostare i puntatori dell'elemento precedente della lista.

Caiodark
14-05-2012, 11:55
Hai provato a debuggare? Sei sicuro che scanf legga correttamente il tuo input?
Inoltre quando cancelli il nodo dalla lista devi ricollegare i due tronconi della medesima, facendo in modo che il nodo che puntava al nodo da cancellare punti al nodo successivo.
Se cancelli l'ultimo nodo allora il penultimo nodo dovrà puntare a null diventando il nuovo ultimo nodo.

goatboy
14-05-2012, 12:23
Originariamente inviato da Caiodark
Hai provato a debuggare? Sei sicuro che scanf legga correttamente il tuo input?
Inoltre quando cancelli il nodo dalla lista devi ricollegare i due tronconi della medesima, facendo in modo che il nodo che puntava al nodo da cancellare punti al nodo successivo.
Se cancelli l'ultimo nodo allora il penultimo nodo dovrà puntare a null diventando il nuovo ultimo nodo.
Qualche consiglio su come fare? :confused:
Ho provato a fare così, modificando una funzione che ci ha dato il professore (che però si riferiva a degli interi):



TList Ricerca_Nodo_Da_Eliminare(TList lista, char nome[]){
TNode *prec=NULL, *curr=lista;
while(curr!=NULL && strcmp(nome, curr->info.nome)>0){
prec=curr;
curr=curr->next;
}
if((curr!=NULL) && strcmp(curr->info.nome, nome)==0){
if(prec==NULL)
lista=curr->next;
else
prec->next=curr->next;
Elimina_Nodo(curr);
}
return lista;
}


Non mi da errori di debug, ma non fa niente :confused:

Who am I
14-05-2012, 12:37
Nel confronto ci va un !=0 anziché > 0.Cambia tutto, se una stringa è maggiore di quella cercata, la strcmp ti restituisce un valore minore di zero, esci dal ciclo ma non ti entra nell' if perché la strcmp non ritorna un valore uguale a zero.



TList Ricerca_Nodo_Da_Eliminare(TList lista, char nome[])
{
TNode prec=NULL, curr=lista;
while(curr!=NULL && strcmp(nome, curr->info.nome)!=0)
{
prec=curr;
curr=curr->next;
}
if((curr!=NULL) && strcmp(curr->info.nome, nome)==0)
{
if(prec==NULL)
lista=curr->next;
else
prec->next=curr->next;
Elimina_Nodo(curr);
}
return lista;
}


Per ora non vedo altri errori, ma può darsi che ce ne siano altri.
Prova a compilare questo codice e facci sapere se funziona.

goatboy
14-05-2012, 13:00
Ho corretto come mi hai detto, e ancora una volta non mi da nessun tipo di errore. Ma dopo aver eliminato, vado a stampare la lista e il nodo non è stato cancellato. Non capisco proprio :confused:

Queste sono le due funzioni che sto utilizzando:



void Elimina_Nodo(TNode *nodo){
free(nodo);
}

TList Ricerca_Nodo_Da_Eliminare(TList lista, char nome[]){
TNode *prec=NULL, *curr=lista;
while(curr!=NULL && strcmp(nome, curr->info.nome)!=0){
prec=curr;
curr=curr->next;
}
if((curr!=NULL) && strcmp(nome, curr->info.nome)==0){
if(prec==NULL)
lista=curr->next;
else
prec->next=curr->next;
Elimina_Nodo(curr);
}
return lista;
}

Who am I
14-05-2012, 14:12
Inserisci una fprintf per vedere se il blocco di codice dell' if viene eseguito:



TList Ricerca_Nodo_Da_Eliminare(TList lista, char nome[]){
TNode *prec=NULL, *curr=lista;
while(curr!=NULL && strcmp(nome, curr->info.nome)>0){
prec=curr;
curr=curr->next;
}
if((curr!=NULL) && strcmp(curr->info.nome, nome)==0){
fprintf(stderr," **** ");
if(prec==NULL)
lista=curr->next;
else
prec->next=curr->next;
Elimina_Nodo(curr);
}
return lista;
}


Se non vengono stampati gli asterischi significa che non entra nell' if, e che la parte da correggere è quella precedente.
In tal caso prova a stampare tutti i risultati delle strcmp eseguite.

goatboy
14-05-2012, 14:19
Originariamente inviato da Who am I
Inserisci una fprintf per vedere se il blocco di codice dell' if viene eseguito.
Se non vengono stampati gli asterischi significa che non entra nell' if, e che la parte da correggere è quella precedente.
In tal caso prova a stampare tutti i risultati delle strcmp eseguite.
Infatti non stampa niente :confused:

Loading