PDA

Visualizza la versione completa : [C] Cancellare un elemento da una lista


donato.sciarra
18-02-2007, 12:47
come seguito di questa discussione (http://forum.html.it/forum/showthread.php?s=&threadid=1090938) apro quest'altra :zizi:

Dopo la pazienza di oregon nel spiegarmi il metodo piu semplice per creare una lista eccomi di nuovo qui per un nuovo problema....

cancellare un elemento creato dinamicamente -.-'

per eliminare un elemento mi serve un puntatore di supporto, che punti all'elemento da eliminare e poi devo far puntare, l'altro puntatore a questo elemento, all'elemento successivo . . . .

ho provato a scrivere del codice ma mi sono bloccato...




void elimina(int codice){
lista *cursore, *supporto;
cursore = testa;
while(cursore->next!=NULL){
if(cursore->codice==codice)/*ho trovato l'elemento da eliminare/
/*a questo punto dovrei uscire dal while e eliminare il nodo trovato ma come posso fare????*/
}



struttura a cui faccio riferimento . . . .



struct nodo{
int codice;
char data[50];
struct nodo *next;
};

typedef struct nodo lista;



grazie a tutti

oregon
18-02-2007, 14:22
Beh, le cose si fanno un pelino piu' complesse ... per fare le cose corrette ho modificato la tua funzione cerca (che, tra l'altro, non funzionava correttamente nel caso di lista vuota ...). La nuova versione cerca l'ho usata anche nella elimina.

La cerca restituisce il puntatore al nodo cercato (se trovato, altrimenti NULL) e restituisce anche il puntatore al nodo precedente (se il nodo trovato e' quello iniziale, il precedente e' NULL). Per restituire un puntatore tramite un parametro, deve essere passato un puntatore a puntatore (ecco il perche' del ** nell'ultimo parametro della cerca).

Queste informazioni sono utili alla funzione elimina per ricostruire correttamente la lista, *senza dimenticare* che la memoria allocata con la malloc, deve essere liberata con la free quando il nodo viene eliminato.

Ovviamente ho adattato il main ...

Naturalmente avrai qualche problemino ad afferrare tutto immediatamente, ma studia il codice con calma e vedrai che ti sara' chiaro ...



lista *cerca(int codice, lista **prec)
{
lista *corr = testa;
*prec = NULL;

while(corr)
{
if(corr->codice==codice) break;
*prec=corr;
corr=corr->next;
}

return(corr);
}

void elimina(int codice)
{
lista *prec, *el = cerca(codice, &prec);
if(el)
{
if(!prec)
testa=el->next;
else
prec->next=el->next;

free(el);
}
}

int main(void)
{
int num;
char data[50];
printf("\n> Liste - - -\n");
printf("codice > ");
scanf("%d", &num);
printf("\ttesto >");
scanf("%s", data);
while(num){
aggiungiElemento(num, data);
printf("\ncodice > ");
scanf("%d", &num);
printf("\ttesto >");
scanf("%s", data);
}
printf("\nImmissione elementi terminata\n");
stampa(testa);

printf("\nElemento da cercare: ");
scanf("%d", &num);

lista *prec, *el = cerca(num, &prec);
if(el)
printf("\nElemento trovato: %s\n", el->data);
else
printf("\nElemento non trovato. . .\n");

elimina(num);
stampa(testa);

system("PAUSE");
return 0;
}

donato.sciarra
18-02-2007, 16:08
dopo una buona ora di scervellamento . . . . credo di aver afferrato !

non e' difficile, ma purtroppo tutto sta a entrare nell'ottica. . . .

commento il codice. . . .


Originariamente inviato da oregon



lista *cerca(int codice, lista **prec)
{
lista *corr = testa;/*assegno al puntatore che uso come cursore nella ricerca la testa
della lista*/
*prec = NULL;/*mentre il puntatore al nodo precedente assegno NULL*/

while(corr)/*finche nn raggiungo la fine della lista*/
{
if(corr->codice==codice) break;/*se il contenuto di codice nel nodo corrispondo
al parametro passato esco dal while*/
*prec=corr;/*altrimenti assegno al puntatore che sta una posizione
prima la stessa in cui si trova il cursore che scandisce la lista*/
corr=corr->next;/*e al puntatore "cursore" il nodo successivo puntato
da next presente nel nodo attuale*/
}

return(corr);/*restituisco come da prototipo un puntatore
fermo nella posizione dell'elemento cercato*/
}

void elimina(int codice)/*ricevo il codice contenuto nel nodo da eliminare*/
{
lista *prec, *el = cerca(codice, &prec);/*creo due puntatori di supporto uno
alla posizione precedente e uno che punta alla posizione dell'elemento da eliminare*/
if(el)/*se el e' diverso da NULL*/
{
if(!prec)/*se l'elemento da eliminare e' in testa alla lista*/
testa=el->next;
else/*altirmenti collego il puntatore presente nel nodo precedente con
l'elemento successivo a quello da eliminare*/
prec->next=el->next;

free(el);/*rendo nuovamente disponibile l'area puntata da el*/
}/*nel caso el fosse NULL significa che o la lista e' vuota o non c'e
niente da eliminare*/
}/*finita la funzione elimina el e prec vanno in pace*/

int main(void){
int num;
char data[50];
printf("\n> Liste - - -\n");
printf("codice > ");
scanf("%d", &num);
printf("\ttesto >");
scanf("%s", data);
while(num){
aggiungiElemento(num, data);
printf("\ncodice > ");
scanf("%d", &num);
printf("\ttesto >");
scanf("%s", data);
}
printf("\nImmissione elementi terminata\n");
stampa(testa);

printf("\nElemento da cercare: ");
scanf("%d", &num);
/*una volta prelevato da terminale l'elemento da cercare
creo due puntatori di supporto per trovare l'elemento che mi interessa
e poi stampare il campo data se trovato*/
lista *prec, *el = cerca(num, &prec);
if(el)
printf("\nElemento trovato: %s\n", el->data);
else
printf("\nElemento non trovato. . .\n");
/*qui in questo caso elimina l'elemento con lo stesso codice di quello
cercato, ovviamente e' possibile sfruttarla diversamente*/
elimina(num);
stampa(testa);

getchar();
getchar();

return 0;
}


:stordita:

oregon
18-02-2007, 17:39
Originariamente inviato da donato.sciarra
dopo una buona ora di scervellamento . . . . credo di aver afferrato !

non e' difficile, ma purtroppo tutto sta a entrare nell'ottica. . . .

commento il codice. . . .

:stordita:

Ok ... ciao ...

Loading