Oppure

Loading
16/03/09 12:56
Chiara87
Ciao!
Dovrei scrivere una funzione che permette di eliminare tutti gli elementi pari da una lista di numeri interi (il cui inserimento termina con 0).

Il problema sta solo nella funzione EliminaPari. Funziona in modo corretto quando la lista inserita inizia con un numero dispari. Se metto però il primo numero pari questo viene saltato e poi gli altri numeri pari vengono eliminati correttamente....
Non riesco però a capire come cancellare il primo elemento se è pari..

Qualcuno mi potrebbe aiutare?! Scusate ma sono alle prime armi con liste e puntatori e sto impazzendo a cercare di capire come eliminare questo primo elemento.. :-|

Grazie ^^
Chiara

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <malloc.h>

typedef struct nl {
        int val;
        struct nl* next;
        } NODOLISTA;
        
int v;


NODOLISTA *InsertLista (NODOLISTA *l, int v)
{
    if (l == NULL) 
    {
       NODOLISTA* t = (NODOLISTA *) malloc(sizeof(NODOLISTA));
       if (t != NULL) 
       {
          t->val = v;
          t->next = NULL;
       }
       return t;
    }     
       else 
    {
          l->next = InsertLista(l->next, v);
          return l;
    }
}
    

NODOLISTA *InsertValore (NODOLISTA *l)
{
      printf("INSERISCI UN VALORE (TERMINI CON 0)");
      scanf ("%d", &v);
      
      if (v == 0)
      printf ("\n\nLISTA->NULL\n\n");
            
      while (v != 0)
      {
      if (v != 0)
      l = InsertLista(l, v);
      scanf ("%d", &v);
      }
      return l;
      
     
}

NODOLISTA *EliminaPari (NODOLISTA *l)
{
NODOLISTA *la=l, *lb;


if (la != NULL)
{
  
      
    	     while (la->next != NULL)
                    {
                     if (la->next->val % 2 != 0) //dispari//
                     {
                     la = la->next;
                     }   	      
                     else
    	                 {
                         lb = la->next;
                         la->next = la->next->next;
                         free(lb);
                         }
                     continue;    
                    }
}
return l;
       
}

void StampaLista (NODOLISTA *l)
{
     if (l != NULL)
     {
           printf("%d\n", l->val);
           StampaLista(l->next);
     }
}

int main () {

NODOLISTA* lInt = NULL;

lInt = InsertValore (lInt);

lInt = EliminaPari (lInt);

StampaLista (lInt);

system ("PAUSE");
return 0;

}
aaa
16/03/09 13:09
theprogrammer
Ti faccio solo notare che, nella EliminaPari, il tuo ciclo per il controllo dei valori inizia da

la->next

operando quindi su la->next->val

In questo modo salti SEMPRE il nodo corrente, ovvero quello puntato da

la

il cui valore e'

la->val
aaa
16/03/09 13:21
Chiara87
si ok, ma quindi cosa dovrei cambiare? Ho provato a metterci un if prima del while in modo tale da cancellare il primo elemento con una free ma mi si blocca sempre... :doubt:

grazie di nuovo
Ultima modifica effettuata da Chiara87 16/03/09 13:21
aaa
16/03/09 14:49
theprogrammer
Scusa, ma la funzione in questione l'hai scritta tu?

Se l'hai scritta tu, da quello che ti ho detto, dovresti saper apportare le modifiche necessarie ...
aaa
16/03/09 15:03
Chiara87
Postato originariamente da theprogrammer:

Scusa, ma la funzione in questione l'hai scritta tu?

Se l'hai scritta tu, da quello che ti ho detto, dovresti saper apportare le modifiche necessarie ...


certo che l'ho scritta io!!

Ho provato ad apportare le modifiche che mi hai detto ma continua a non funzionarmi..

NODOLISTA *EliminaPari (NODOLISTA *l)
{
NODOLISTA *la=l, *lb;

    	     while (la->next != NULL)
                    {
                       if ((la->val % 2) != 0)
                       {
                          la = la->next;
                       }   	      
                       else
   	                   {
                          lb = la->next;
                          la->next = lb->next;
                          free(lb);
                       }
                    }
return l;             
      
}


cosa sbaglio?
aaa
16/03/09 16:00
theprogrammer
NODOLISTA * EliminaPari(NODOLISTA *l)
{
	NODOLISTA *canc, *tmp=l;
    
	while(tmp && (tmp->val % 2)==0)
	{ 
		l = l->next;
		free(tmp);
		tmp = l;
	}

	while(tmp)
		if(tmp->next && (tmp->next->val % 2)==0)
		{
			canc = tmp->next;
			tmp->next = tmp->next->next;
			free(canc);
		} else 
			tmp = tmp->next;
        
	return l; 
}
aaa
16/03/09 16:38
Chiara87
Postato originariamente da Chiara87:

Postato originariamente da theprogrammer:

Scusa, ma la funzione in questione l'hai scritta tu?

Se l'hai scritta tu, da quello che ti ho detto, dovresti saper apportare le modifiche necessarie ...


certo che l'ho scritta io!!

Ho provato ad apportare le modifiche che mi hai detto ma continua a non funzionarmi..

NODOLISTA *EliminaPari (NODOLISTA *l)
{
NODOLISTA *la=l, *lb;

    	     while (la->next != NULL)
                    {
                       if ((la->val % 2) != 0)
                       {
                          la = la->next;
                       }   	      
                       else
   	                   {
                          lb = la->next;
                          la->next = lb->next;
                          free(lb);
                       }
                    }
return l;             
      
}


cosa sbaglio?



ok perfetto, grazie 1000 :k:!! Ho trovato anche un altro tipo di soluzione facendo uso di un terzo puntatore ausiliario che mi scorre tutti gli elementi pari ad inizio lista!

NODOLISTA *EliminaPari (NODOLISTA *l)
{
   NODOLISTA *la, *lb, *lc;
   lc = l;

   if (lc != NULL)
   {
       while ((lc != NULL) && ((lc->val %2) == 0))
       {
           lc = lc->next;
       }
   }

    la = lc;

   if (la != NULL)
   {
       while (la->next != NULL)
       {
           if (la->next->val % 2 != 0)
           {
               la = la->next;
           }
           else
           {
               lb = la->next;
               la->next = lb->next;
               free(lb);
           }
       }
   }
   return lc;
}
aaa
20/03/09 11:51
gigisoft
Postato originariamente da theprogrammer:

NODOLISTA * EliminaPari(NODOLISTA *l)
{
	NODOLISTA *canc, *tmp=l;
    
	while(tmp && (tmp->val % 2)==0)
	{ 
		l = l->next;
		free(tmp);
		tmp = l;
	}

	while(tmp)
		if(tmp->next && (tmp->next->val % 2)==0)
		{
			canc = tmp->next;
			tmp->next = tmp->next->next;
			free(canc);
		} else 
			tmp = tmp->next;
        
	return l; 
}



Cosi' dovrebbe essere ancora piu' semplice ( con un solo ciclo while ):

NODOLISTA * EliminaPari(NODOLISTA *l)
{
 NODOLISTA *canc, *tmp1 = NULL, tmp2 = l;

 while(tmp2)
  {
   if (tmp2->val % 2)==0)
      {
       canc = tmp2;

       if (tmp1)
          { tmp1->next = tmp2->next; }
       else
          { l = l->next; }

          free(canc);
      }
   else 
      { tmp1 = tmp2; }

   tmp2 = tmp2->next;
  }
     
 return l; 
}

aaa