Lista ordinata

di il
17 risposte

Lista ordinata

Salve a tutti..!

Ho da proporvi il classico problema del fine settimana..

..stavolta l'esercizio è quello dell'inserimento ordinato in una lista..ad esempio se noi inseriamo 3-5-7 e poi vogliamo inserire il 6 esso deve essere inserito tra il 5 e il 7..

..ecco, io per l'inserimento avrei pensato di farlo in questo modo..
      nuovo=new nodo;  
                    cout<<"inserisci elemento"<<"\n";
                    cin>>nuovo->num;
                    if(testa==NULL)
                    {
                       nuovo->succ=NULL;
                       testa=nuovo;
                    }
                    else
                    {
                       p=testa; 
                       while((p==NULL)&&(trova==0))
                       {
                          if(nuovo->num<p->num)
                          {
                            if(conta==0)
                            {
                               nuovo->succ=testa;
                               testa=nuovo;
                               trova=1;
                            }
                            else
                            {
                              prec->succ=nuovo;
                              nuovo->succ=p;
                            }
                          }
                          else
                          {  
                            p->succ=nuovo;  
                            prec=p;
                            nuovo->succ=NULL;
                            conta++;                                                         
                          }       
 
..e logicamente sembra giusto, però quando è il momento di stampare la lista mi stampa solo il primo elemento.. ..perchè??

..se c'è qualche istruzione che non vi è chiara nell'inserimento, ovviamente ditemelo pure..

17 Risposte

  • Re: Lista ordinata

    Controlla sta parte
    
    while((p==NULL)&&(trova==0))
    p == NULL ?
  • Re: Lista ordinata

    Uhm..vero..sarebbe p->succ!=NULL..

    ..però anche così non cambia nulla..!!
  • Re: Lista ordinata

        //inserimento          
             case 2:
                   {
                        nuovo=new nodo;  
                        cout<<"inserisci elemento"<<"\n";
                        cin>>nuovo->num;
                        if(testa==NULL)
                        {
                           nuovo->succ=NULL;
                           testa=nuovo;
                           p=testa;
                        }   
                        else
                        {
                             if(nuovo->num<p->num)
                             {         
                               if(nuovo->num<testa->num)
                               {     
                                 nuovo->succ=testa;
                                 testa=nuovo;
                               }
                             }
                             else
                            {  
                              nuovo->succ=NULL;  
                              p->succ=nuovo;
                              p=nuovo;                                      
                            }
                        }   
     
    ..ho modificato il programma..adesso se inserisco 3-5-7 me li stampa..se inserisco un numero più piccolo della testa (ad esempio 2), lo inserisce correttamente prima del 3 e mi stampa 2-3-5-7..il problema è quando devo inserire il 4 o il 6..perchè così mi si inseriscono alla fine, dopo il 7..ma come posso fare per riuscire ad inserirli correttamente tra un nodo e l'altro??
  • Re: Lista ordinata

    Che ne dici di questo metodo
    
    case 2:
    {
    	nodo *p = NULL;
    	nuovo=new nodo; 
    	nuovo->next = NULL;
    	cout<<"inserisci elemento"<<"\n";
    	cin>>nuovo->num;
    	if(testa==NULL)
    	{
    		nuovo->succ=NULL;
    		testa=nuovo;
    	}   
    	else
    	{
    		if(testa->num > nuovo->num) //inserimento in testa
    		{
    			nuovo->succ = testa;
    			testa = nuovo;
    		}
    		else
    		{
    			p = testa;
    			while(p->succ != NULL && p->succ->num < nuovo->num)
    				p = p->succ;
    			if(p->succ == NULL) //inserimento in fondo 
    			{
    				p->succ = nuovo;
    			}
    			else //inserimento in mezzo
    			{
    				nuovo->succ = p->succ;
    				p->succ = nuovo;
    			}
    		}
    	}   
    }
    
  • Re: Lista ordinata

    Uhm..così se inserisco 3-5-7 mi si stampa 3-7-5...l'inserimento in testa va bene..se invece inserisco il 4, la stampa è 3-7-5-4...c'è ancora qualcosa che non va..
  • Re: Lista ordinata

    Posta il programma completo, vediamo cosa c'è che non va. cambia il while così intanto:
    
     while(p->succ != NULL && p->succ->num < nuovo->num)
                p = p->succ;
    
  • Re: Lista ordinata

    Non ci crederai ma cambiando il while funziona!!!

    ..adesso voglio provare ad analizzarlo da solo, semmai se ho qualche dubbio su qualche istruzione, ti chiedo delucidazioni ok?

    ..intanto ti ringrazio, come sempre, immensamente..
  • Re: Lista ordinata

    Ci credo si, ho capito il mio errore
  • Re: Lista ordinata



    ..comunque mi è chiaro quasi tutto il meccanismo..una cosa sola però non capisco..
      p = testa;
                while((p->succ != NULL) && (p->succ->num < nuovo->num))
                 p = p->succ;
     
    ..queste 3 istruzioni e soprattutto le 2 condizioni che hai inserito all'interno del while, cosa sono e a cosa servono di preciso??
  • Re: Lista ordinata

    Allora parti da sopra perche centra anche l'if sopra. sopra controlli se la testa ha un numero > di quello che vuoi inserire, se no significa che il numero che vuoi inserire si trova dopo la testa. Prima controlli se p->succ è NULL e poi se il numero di p->succ è minore del numero nuovo. Quindi quando il while esce, esce per due ragioni:
    1. ha raggiunto la fine della lista e non ha trovato un numero minore di quello che vuoi inserire (significa che il numero verrà aggiunto alla fine della lista)
    2. ha trovato una poszione adatta da inserire il numero in mezzo alla lista. Siccome la tua lista è ad una via cioè solo succ e non succ/prec ho fatto in modo che quando si ferma, si fermi non nella posizione dove verrà inserito l'elemento ma un elemento prima così che p->succ punta sempre alla posizione dove verrà inserito questo elemento.
  • Re: Lista ordinata

    Ehm...altro problema..

    ..oltre all'inserimento e alla stampa, la mia prof. mi ha chiesto di effettuare anche l'estrazione in qualsiasi parte della lista...

    bene..io ho proposto la seguente soluzione..
       //estrazione     
              case 4:
                   {
                     if(testa==NULL)
                     cout<<"lista vuota"<<"\n";
                     else
                     {
                        trova=0; 
                        p=testa; 
                        ptr=testa; //inizializziamo la variabile trova a 0 e assegniamo sia a p che a ptr il contenuto di testa
                        cout<<"quale elemento vuoi estrarre?"<<"\n";
                        cin>>n; 
                        while((ptr->succ!=NULL)&&(trova==0)) //fino a quando il campo succ della variabile dinamica puntata da ptr è diverso da NULL e trova è uguale a 0
                        { 
                          if(testa->num==n)
                          {
                            cout<<"l'elemento e' stato estratto"<<"\n";
                            if(ptr->succ==NULL)
                            {
                              testa=NULL;
                              p=p->succ;
                              ptr=ptr->succ;
                              trova=1;
                            }  
                            else
                            {
                               testa=testa->succ;
                               trova=1;
                            }    
                          } //se l'elemento che vogliamo estrarre si trova in testa la lista viene estratto subito e, incrementando la variabile trova, evitiamo di scorrere inutilmente
                          //tutti i nodi della lista                
                          else
                          {
                            p=ptr;  
                            ptr=ptr->succ;
                          } //altrimenti in p memorizziamo il contenuto di ptr e ptr viene aggiornata e punta al nodo successivo
                          if(trova==0)
                          {
                            if(ptr->num==n)
                            {
                              cout<<"l'elemento e' stato estratto"<<"\n";
                              p->succ=ptr->succ;
                              trova=1;
                            }  
                          }  //se trova è uguale a 0 e se il numero contenuto nel campo num della variabile dinamica puntata da ptr è uguale al numero che vogliamo estrarre//
                          //allora il campo succ del nodo precedente punterà al nodo successivo al quale puntava, prima di essere estratto, ptr 
                        }  
                       if((ptr->succ==NULL)&&(trova==0)) 
                       {    
                         if(ptr->num==n)
                         {
                            cout<<"l'elemento e' stato estratto"<<"\n";
                            p->succ=NULL;
                         }
                        else 
                        cout<<"elemento non presente"<<"\n"; //se alla fine di tutti i controlli trova rimane ancora uguale a 0, allora l'elemento non è presente nella lista 
                      } 
    
    ..che non è sbagliata, perchè l'estrazioni le effettua correttamente..però c'è sempre il solito "piccolo" problemino..e cioè..se io inserisco 3-4-5 nella lista ed estraggo nell'ordine 4-5-3, quando poi vado a stampare la lista, non mi spunta il messaggio "lista vuota" come dovrebbe, ma spunta solo l'elemento in testa, cioè in questo caso 3.. ..non riesco a far andare testa a NULL, anche se ho messo un'istruzione che dovrebbe farla puntare a NULL..aiutatemi voi, please..!
  • Re: Lista ordinata

    Perche fai mille if/else quando sta roba si può fare molto meglio e senza errori?
    
    if(testa == NULL)
    		printf("Lista vuota, elemento non trovato\n");
    	else
    	{
    		if(testa->num == n)
    		{	
    			printf("elemento trovato in testa\n");
    			ptr = testa;
    			testa = testa->succ;
    			delete ptr;
    		}
    		else
    		{
    			ptr = testa;
    			while(ptr->succ != NULL && ptr->succ->num != n)
    				ptr = ptr->succ;
    			if(ptr->succ == NULL) //ultimo elemento
    			{
    				printf("elemento non trovato\n");
    			}
    			else
    			{
    				if(ptr->succ->num == n) //trovato
    				{
    					printf("Elemento trovato\n");
    					ptr2 = ptr->succ;
    					ptr->succ = ptr2->succ;
    					delete ptr2;
    				}
    			}
    		}
    	}
    
  • Re: Lista ordinata

    Mi piace complicarmi la vita..!

    ..ti ringrazio....ma mi puoi dire a cosa serve l'istruzione free(ptr) o free(ptr2)?
  • Re: Lista ordinata

    L'ho modificata in delete. free è una funzione C per liberare lo spazio di memoria non + in uso, ma siccome tu stai lavorando in C++ e stai usando il new, bisogna usare il corrispettivo delete.


Devi accedere o registrarti per scrivere nel forum
17 risposte