Cancellare nodo lista semplice C

di il
3 risposte

Cancellare nodo lista semplice C

Ciao a tutti,
sto lavorando su una lista semplice e ho una specifica che mi richiede di cancellare tutti i nodi che soddisfino una determinata condizione di cancellazione. Per vari motivi, che sono legati alle altre specifiche e alla mia voglia di creare un set di funzioni che opportunamente messe insieme mi facciano compiere azioni diverse, avevo pensato al seguente codice:
case 14:
            input_ricerca=1;
            stopi=0;
            contatore=0;
            temp=testa;
            salta_testa=0;
            while(temp->next)
            {
                if(!looking(9,&temp))
                {
                    canc_articolo(&temp);
                    temp=testa;
                    operazione_testa=0;
                }
                else /*if(salta_testa)*/
                    temp=temp->next;
            }
        break;
per il main
per la funzione int looking(int scelta_f,nodo **temp_f)
case 9:
        if(input_ricerca)
        {
            printf("\ninserimento condizione di cancellazione\n");
            fflush(stdout);
            scanf("%d",&condizione);
            clean_stdin();
            input_ricerca=0;
        }
        if(!salta_testa&&testa->codice==condizione)
        {
            operazione_testa=1;
            return(0);
        }
        else
            salta_testa=1;
        if((*temp_f)->next&&(*temp_f)->next->codice==condizione)
            return(0);
        return(1);
        break;
e per la funzione cancella vera e propria
void canc_articolo(nodo **temp_f)
{
    nodo *temp_target;
    if(!operazione_testa)
    {
        printf("\nCnC\n");
        fflush(stdout);
        temp_target=(*temp_f)->next;
        (*temp_f)->next=temp_target->next;
        free(temp_target);
    }
    else
    {
        printf("\nCtC\n");
        fflush(stdout);
        testa=testa->next;
        free((*temp_f));
    }
    printf("\nC\n");
    fflush(stdout);
    return;
}
inutile dire che il codice non funziona bene, cancella sempre in testa anche se ogni tanto, senza capire perche' pare si metta a funzionare correttamente!
A voi salta niente all'occhio?

ciao Igor

3 Risposte

  • Re: Cancellare nodo lista semplice C

    Ciao, interpretare le righe di codice altrui è abbastanza complicato, ma a volte la lettura potrebbe esserci facilitata da alcuni commenti... Comunque, io in effetti non riesco a capire perchè ti serva usare delle variabili per cercare di saltare la testa della lista e perchè vuoi prima cercare il nodo da eliminare, se tanto devi deallocare tutti quelli che hanno quel codice, vorrei invece suggerirti di usare una funzione per l'eliminazione ricorsiva, quindi eliminando la parte di ricerca e i vari if, cioè qualcosa del tipo:
    (Tieni conto che uso *laLista perchè ho passato un nodo * *, quindi DOPPIO puntatore a nodo)
    
    /* Premettendo che ovviamente dal main avrai già letto la condizione di eliminazione,
        puoi definire la funzione canc_articolo in questo modo */
        
    void canc_articolo (int codice, TipoLista *laLista){ /* TipoLista sarebbe nodo *  */
        nodo *aux; /* Un puntatore a nodo ausiliario, per l'eliminazione */
        if (!(*laLista)) /* Per prima cosa, se la lista è vuota, esco */
          return;
        if ((*laLista)->codiceArticolo == codice)){ /* Quindi se questo nodo è quello che cercavo */
          aux = *laLista; /* Punto aux a questo nodo */
          *laLista = (*laLista)->next; /* Invece sposto la lista sul nodo successivo */
          free(aux); /* E poi dealloco quel nodo */
          /* Se però ci sono più elementi con quel codice? allora chiamo di nuovo la funzione */
          canc_articolo (codice, laLista); /* Occhio che ora laLista punta già al nodo successivo! */
        }
       /* Se però l'elemento da eliminare non era questo (cioè diciamo "il primo") 
           richiamo la funzione, ma sul successivo */
         else canc_articolo (codice, &(*laLista)->next);
         /* E da qui in poi, in pratica, scorro tutta la lista, appena trovo un nodo da 
            eliminare, ne sposto il puntatore al nodo successivo e poi lo elimino (con aux),
            ma poi controllo sul resto della lista, cioè proprio sul nodo successivo!
            Alla fine, si arriverà al caso base di lista vuota, perchè un next sarà di sicuro
            NULL, quindi la funzione fa return e poi,  */
    return; /* tramite questo return, si chiudono anche tutti gli altri record di attivazione */
    }
    
    Preciso che ho scritto il codice qui sul forum e non l'ho provato, ma dovrebbe essere abbastanza corretto...
    Spero di essere stato chiaro e di averti suggerito una soluzione più facile da scrivere, buona programmazione e alla prossima
  • Re: Cancellare nodo lista semplice C

    Ciao, scusa per i mancati commenti...hai perfettamente ragione, si fatica a seguire...
    In ogni caso ho seguito il tuo consiglio e ho sfruttato il tuo codice che funzionava perfettamente
    grazie mille!
    La tua risposta mi e' stata veramente utile e sto riscrivendo anche altre funzioni sfruttando la ricorsivita'!

  • Re: Cancellare nodo lista semplice C

    Mi fa piacere averti aiutato
    Buona programmazione!
Devi accedere o registrarti per scrivere nel forum
3 risposte