Come elimino piu' elementi (simili) in una lista?

di il
7 risposte

Come elimino piu' elementi (simili) in una lista?

Per ora sono riuscito a fare questo:

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

struct el{
	int Num;
	struct el *next;
};

typedef struct el ElementoLista;
typedef ElementoLista *Lista;

//Prototipi
Lista CaricaLista(Lista);
Lista ElimEle(Lista p, int x);
void StampaLista(Lista);

int main()
{
	Lista List;
	int x, risp;
	List = CaricaLista(List);
	
	StampaLista(List);
	printf("\n");
	
	printf("vuoi eliminare? ");
	scanf("%d", &risp);
	
	while(risp == 1)
	{
		printf("Inserisci  l'elemento da eliminare: ");
		scanf("%d", &x);
		List = ElimEle(List, x);
		StampaLista(List);
		printf("\nvuoi eliminare? ");
		scanf("%d", &risp);
	
	}
	
	
	
	
		
	return 0;
}

Lista CaricaLista(Lista p)
{
	Lista punt;

	p = (Lista)malloc(sizeof(ElementoLista));
	
	p->Num = rand()%10;


	punt = p;
	
	for(int i = 1; i < 5; i++)
	{
		punt->next = (Lista)malloc(sizeof(ElementoLista));
		punt = punt->next;
		punt->Num = rand()%10;
		
		
	}
	punt->next = NULL;
	
	return p;
}

Lista ElimEle(Lista p, int x)
{
	Lista prev,cur;
	prev = NULL;
	cur = p;

	while(cur!=NULL)
	{

		if(cur->Num == x )
		{
	
			if(prev == NULL)
			{
				p = cur->next;
				free(cur);
				return p;	
			}
			else 
			{
				
				prev->next = cur->next;
				free(cur);	
				return p;
			}
		}	
		
		prev = cur;
		cur = cur->next;
	
	}
	
	return p;
}

void StampaLista(Lista p)
{
	printf("Lista->");
	

	while(p!=NULL)
	{
		printf("%d ->", p->Num);
		
		p = p->next;
	}
	
	printf("NULL");
}

7 Risposte

  • Re: Come elimino piu' elementi (simili) in una lista?

    Che significa per te "simili"? Uguali o quasi uguali ...?

    Cosa non va nel tuo codice? Che problemi/errori hai? Che prove hai fatto?

    Cosa ti aspetti che si risponda se non dai dettagli?
  • Re: Come elimino piu' elementi (simili) in una lista?

    Scusate se mi sono espresso male, per simili intendo uguali. Il mio codice non da problemi, riesco ad eliminare gli elementi ma ripetendo piu' volte la stessa funzione, grazie al while nel main. Vorrei, invece, che all'inserimento di un numero, la funzione mi elimini tutti gli elementi UGUALI al elemento di input, in maniera automatica.
  • Re: Come elimino piu' elementi (simili) in una lista?

    Prima di risponderti vorrei fare alcune osservazioni:
    - la funzione CaricaLista() non mi sembra un buon approccio per la creazione di una lista. Se vuoi un consiglio prova ad implementare una funzione che aggiunge un elemento in testa alla lista e una che lo aggiunge in coda;
    - non so se sia voluto, in ogni caso relativamente alla funzione CaricaLista() ti sei accorto che i valori aggiunti sono sempre gli stessi? Ti dice niente la funzione srand()?
    - perchè passi l'argomento Lista p alla funzione CaricaLista()?

    Tornando alla questione principale, mi vengono in mente due modi per eliminare gli elementi uguali in modo automatico:
    - la funzione ElimEle() continua ad eliminare un solo elemento alla volta, ma invece che una Lista gli fai ritornare vero (1) se un elemento viene rimosso e falso (0) altrimenti. Nel main basterà quindi scrivere:
    while(ElimEle(&testa, x));
    - se invece vuoi che tutto avvenga all'interno della funzione bisogna ragionare un po'... innanzitutto sarà necessario scorrere la lista fino alla fine e quindi bisogna lasciare solo il return finale. Nel momento in cui togli i 2 return intermedi, le istruzioni:
    prev = cur;
    cur = cur->next;
    vengono eseguite sempre, a prescindere che la condizione
    if(cur->Num == x)
    sia rispettata o meno. Secondo te va bene o bisogna aggiustare il tiro?
  • Re: Come elimino piu' elementi (simili) in una lista?

    Ciao, grazie per la risposta.
    Per le tue osservazioni ti rispondo che, facendo in quel modo, penso che stia inserendo in coda, ho imparato solo quel metodo.
    Quale sarebbe il vantaggio nel imparare entrambi? Magari sapendolo gli daro' un'occhiata.
    Per il passaggio del parametro lista, e' vero, potevo anche non metterlo, hai ragione.
    Con la funzione rand() non volevo fare altro che aggiungere velocemente elementi alla lista, in modo da potermi concentrare maggiormente sulla risoluzione del problema.

    Passando al problema invece...
    Anche prima di chiedere aiuto su questo forum avevo provato a far terminare il ciclo senza alcun return, pero', per qualche ragione il ciclo non va avanti, non riesco a capirne il motivo.
    Ho provato a mettere un contatore per capirne di piu'... Il ciclo while va all'infinito mentre provando a mettere la stampa nell'else, quindi per verificare se mi ritorna la posizione dell'elemento, ho notato che si ferma al primo(elemento uguale ad x).
    Quindi suppongo che il while non raggiunga il NULL per questo motivo... Come potrei risolvere?
  • Re: Come elimino piu' elementi (simili) in una lista?

    Quale sarebbe il vantaggio nel imparare entrambi? Magari sapendolo gli daro' un'occhiata.
    Aggiungere un elemento in testa o in coda rientrano tra le operazioni standard che devono poter essere effettuate su una lista.
    Inoltre se hai chiaro il concetto di lista, puoi scrivere le due funzioni anche da solo, senza "studiarle" da altre fonti.
    Per renderti conto dell'utilità di una funzione aggiungi_in_coda(), ecco come avresti potuto sostituire la funzione CaricaLista():
    int main()
    {
       lista testa;
       for(unsigned int i = 0; i < 10; ++i)
       {
           testa = aggiungi_in_coda(testa, i);
       }
    }
    Con la funzione rand() non volevo fare altro che aggiungere velocemente elementi alla lista, in modo da potermi concentrare maggiormente sulla risoluzione del problema.
    Capisco, ma se non inizializzi il seme del generatore di numeri casuali con la funzione srand(), ogni volta che lancerai il programma avrai sempre la stessa sequenza di numeri.
    Passando al problema invece...
    Anche prima di chiedere aiuto su questo forum avevo provato a far terminare il ciclo senza alcun return, pero', per qualche ragione il ciclo non va avanti, non riesco a capirne il motivo.
    Ho provato a mettere un contatore per capirne di piu'... Il ciclo while va all'infinito mentre provando a mettere la stampa nell'else, quindi per verificare se mi ritorna la posizione dell'elemento, ho notato che si ferma al primo(elemento uguale ad x).
    Quindi suppongo che il while non raggiunga il NULL per questo motivo... Come potrei risolvere?
    Non ho capito bene quello che intendi, magari posta il codice con le modifiche che hai apportato.
    In ogni caso ragiona su quello che ti ho detto nel precedente post:
    - se invece vuoi che tutto avvenga all'interno della funzione bisogna ragionare un po'... innanzitutto sarà necessario scorrere la lista fino alla fine e quindi bisogna lasciare solo il return finale. Nel momento in cui togli i 2 return intermedi, le istruzioni:
    prev = cur;
    cur = cur->next;
    vengono eseguite sempre, a prescindere che la condizione
    if(cur->Num == x)
    sia rispettata o meno. Secondo te va bene o bisogna aggiustare il tiro?
    Per aiutarti nel ragionamento non aver paura di ricorrere a carta e penna!
  • Re: Come elimino piu' elementi (simili) in una lista?

    Grazie per l'aiuto.
    Seguendo i tuoi consigli e facendomi aiutare con carta e penna sono riuscito a risolvere un problema che oramai erano giorni che cercavo di risolverlo... Mai sottovalutare la carta, ora lo so. Hahahah

    Posto il codice per chi si ritrovera' nella mia stessa situazione:
    
    Lista ElimEle(Lista p, int x)
    {
    	Lista prev,cur;
    	prev = NULL;
    	cur = p;
    	
    
    	while(cur!=NULL)
    	{
    
            if(cur->Num == x )
    		{
    
    			if(prev == NULL)
    			{
    
    				p = cur->next;
    				free(cur);
    				cur = p;
    
    
    			}
    			else
    			{
                 
    				prev->next = cur->next;
    				free(cur);
                			cur = prev;
    
    
    
    			}
    		}
    		prev = cur;
                    cur = cur->next;
    
    
    		
    	}
    
    	return p;
    }
    

    p.s. Ammetto di essermi sentito uno stupido quando ho scoperto il problema... posso consolarmi dicendo che per le mie capacita' era un bel grattacapo, vai a saperlo che quando la memoria viene deallocata perde il punto. Anche perche' quando usavo il return veniva stampata correttamente, quindi mi allontanavo dal problema principale
  • Re: Come elimino piu' elementi (simili) in una lista?

    Mai sottovalutare la carta, ora lo so. Hahahah


    Per quanto riguarda il codice adesso va quasi bene, ma c'è ancora qualcosa da aggiustare...
    Se provi ad eliminare tutti gli elementi della lista, ti accorgerai che al momento di eliminare l'ultimo elemento il programma crasha.
    Il motivo sta nell'osservazione fatta nel mio primo post in questo topic e che ti ho quotato anche nel post precedente. In ogni caso per rendertene conto considera una lista formata da un solo elemento e simula su carta quello che succede.
Devi accedere o registrarti per scrivere nel forum
7 risposte