Problema con lista lineare

di il
28 risposte

28 Risposte - Pagina 2

  • Re: Problema con lista lineare

    Si questo l'ho fà già la funzione insl_nodo che ho postato prima, il problema è che devo prima (giustamente) individuare punt a chi deve puntare. QUindi partendo da una lista vuota io inserisco il primo elemento in testa: luca-21...di conseguenza p_next=NULL perchè c'è solo un elemento.
    Ora se io voglio inserire un'altro elemento devo prima confrontare il nome che voglio inserire con il nome già presente, quindi volendo inserire: sara-17 lo confornto con il nodo già esistente, se è maggiore lo aggiungo in cosa, se no in testa.
    Ora che ho 2 elementi e ne voglio aggiungere un terzo, ad esempio marco-20, visito la lista fino a che non trovo un elemento maggiore del mio, mi fermo alla posizione prima e faccio il procedimento di inserimento in mezzo.
    Teoricamente così è corretto? mi sono dimenticato qualcosa??
  • Re: Problema con lista lineare

    Ora ho creato anche una funzione per l'inserimento in coda, però appena inserisco il secondo nome il primo assume valori random sia se uso la funzione in testa sia quella in cosa, perde il valore precedentemente meorizzato, come faccio per conervarlo?
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    typedef struct{
                char nome[20];
                short eta;} Info;
    typedef struct persona{
               Info info;
               struct persona *p_next;} Persona;
    
    
    void insl_testa(Info , Persona **);
    void insl_coda (Info , Persona **);
    void insl_nodo(Info , Persona **);
    void print_lista(Persona *);
    void main ()
    {
       int op, menu=100;
       Persona *head, *punt;
       Info dato;
       head=NULL;//creiamo la lista
    
       while (menu<=100)
       {
          puts("\n\n\n=======================");
          puts("GESTIONE DI UNA LISTA");
          puts("=======================\n\n");
          puts("Selezionare l'operazione:\n");
          puts("1=Visualizzare la lista");
          puts("2=Inserire un elemento");
          puts("3=eliminare un elemento");
          scanf("%d",&op);
    
          switch (op)
          {
             case 1: print_lista(head); break;
    
             case 2 :if (head==NULL){
                        printf("Inserie il nuovo nome: ");scanf("%s",dato.nome);
                        printf("Inserie l'eta': ");scanf("%d",&dato.eta);
                        insl_testa(dato,&head);break;}
                    else{
                        printf("Inserie il nuovo nome: ");scanf("%s",dato.nome);
                        printf("Inserie l'eta': ");scanf("%d",&dato.eta);
                            if(strcmp(punt->info.nome,dato.nome)<0){
                                insl_testa(dato,&head);}
                            else{
                                insl_coda(dato,&head);}
    
                         }; break;
           }
       }
    }
    void insl_testa (Info dato, Persona **p_head)
    {
       Persona *ptr;
       ptr=calloc(1,sizeof(Persona));//allochiamo memoria per il nuovo nodo
       //assegna alla nuova memoria allocata il nuovo nodo
       ptr->info=dato;
       ptr->p_next=*p_head;//il puntatore successivo assume il valore di quello di testa (cioè il punt di testa non è più di testa)
       *p_head=ptr;//aggiorniamo head al nuovo nodo, il nuovo nodo diventa puntato dal puntatore di testa
    }
    /*void insl_nodo(char dato_n[20], short dato_e, struct persona **p_punt)
    {
       struct persona *ptr;
       ptr=calloc(1,sizeof(struct persona));
       strcpy(ptr->nome,dato_n);
       ptr->eta=dato_e;
       ptr->p_next=(*p_punt)->p_next;
       (*p_punt)->p_next=ptr;
       *p_punt=ptr;
    }*/
    void insl_coda (Info dato, Persona **p_head)
    {
        Persona *ptr;
        ptr=calloc(1,sizeof(Persona));
        ptr->info=dato;
        ptr->p_next=NULL;
        (*p_head)->p_next=ptr;
    }
    void print_lista(Persona *pl)
    {
       printf("\n\n");
       printf("lista: \n");
       while (pl){
          printf("%s\t%d\n", pl->info.nome,pl->info.eta);
          pl = pl->p_next;
             }
       printf("\n\n");
    }
    
  • Re: Problema con lista lineare

    Cmq prova il tuo metodo e te ne accorgerai che ogni cella avrà li stessi valori.
    Te lo scritto prima ma non ci hai creduto. Non puoi assegnare le strutture in quel modo. Devi usare sctrcpy per i membri char array della strttura.
  • Re: Problema con lista lineare

    skynet ha scritto:


    Cmq prova il tuo metodo e te ne accorgerai che ogni cella avrà li stessi valori.
    Te lo scritto prima ma non ci hai creduto. Non puoi assegnare le strutture in quel modo. Devi usare sctrcpy per i membri char array della strttura.
    ok perfetto ho di nuovo eliminato la variabile età per comodità (la inserisco dopo)....ora solo con la variabile nome e la sctrcpy come hai detto tu mi salva solo gli ultimi due elementi che ho inserito, ti passo il codice e scusami per tutta questa insistenza, ma devo fare un esame ed è un argomento ostico per me, grazie per tutto
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    typedef struct persona{
               char nome[20];
               struct persona *p_next;} Persona;
    
    
    void insl_testa(char [] , Persona **);
    void insl_coda(char [] , Persona **);
    void print_lista(Persona *);
    void main ()
    {
       int op, menu=100;
       Persona *head, *punt;
       char dato[20];
       head=NULL;//creiamo la lista
    
       while (menu<=100)
       {
          puts("\n\n\n=======================");
          puts("GESTIONE DI UNA LISTA");
          puts("=======================\n\n");
          puts("Selezionare l'operazione:\n");
          puts("1=Visualizzare la lista");
          puts("2=Inserire un elemento");
          puts("3=eliminare un elemento");
          scanf("%d",&op);
    
          switch (op)
          {
             case 1: print_lista(head); break;
             case 2 :if(head==NULL){
                        printf("Inserie il nuovo nome: ");scanf("%s",dato);
                        insl_testa(dato,&head);}
                   else{
                       printf("Inserie il nuovo nome: ");scanf("%s",dato);
                        if(strcmp(head->nome,dato)>0)
                            insl_testa(dato,&head);
                        else
                            insl_coda(dato,&head);}
             break;
           }
       }
    }
    void insl_testa (char dato[20], Persona **p_head)
    {
       Persona *ptr;
       ptr=calloc(1,sizeof(Persona));//allochiamo memoria per il nuovo nodo
       strcpy(ptr->nome,dato);//assegna alla nuova memoria allocata il nuovo nodo
       ptr->p_next=*p_head;//il puntatore successivo assume il valore di quello di testa (cioè il punt di testa non è più di testa)
       *p_head=ptr;//aggiorniamo head al nuovo nodo, il nuovo nodo diventa puntato dal puntatore di testa
    }
    void insl_coda(char dato[20], struct persona **p_head)
    {
       struct persona *ptr;
       ptr=calloc(1,sizeof(struct persona));
       strcpy(ptr->nome,dato);
       (*p_head)->p_next=ptr;
        ptr->p_next=NULL;
    }
    void print_lista(Persona *pl)
    {
       printf("\n\n");
       printf("lista: ");
       while (pl){
          printf("%s\n", pl->nome);
          pl = pl->p_next;
             }
       printf("\n\n");
    }
  • Re: Problema con lista lineare

    Prova questo
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct persona
    {
    	char nome[20];
    	short eta;
    	struct persona *p_next;
    }Persona;
    
    
    void inserisci_campo(Persona **);
    void print_lista(Persona *);
    
    int main ()
    {
    	int op, menu=100;
    	Persona *head = NULL;
    		
    	while (menu<=100)
    	{
    		puts("\n\n\n=======================");
    		puts("GESTIONE DI UNA LISTA");
    		puts("=======================\n\n");
    		puts("Selezionare l'operazione:\n");
    		puts("1=Visualizzare la lista");
    		puts("2=Inserire un elemento");
    		puts("3=eliminare un elemento");
    		scanf("%d",&op);
    
    		switch (op)
    		{
    			case 1: print_lista(head); break;
    			case 2 : inserisci_campo(&head); break;
    			break;
    		}
    	}
    }
    
    void inserisci_campo(Persona **head)
    {
    	Persona *nuovo_campo = (Persona *)calloc(1,sizeof(struct persona));
    	if(nuovo_campo != NULL)
    	{
    		printf("Inserisci nome:\t");
    		scanf("%s",nuovo_campo->nome);
    		printf("inserisci eta\':\t");
    		scanf("%d",&nuovo_campo->eta);
    		nuovo_campo->p_next = NULL;
    		if(*head == NULL)
    		{
    			*head = nuovo_campo;
    		}
    		else
    		{
    			Persona *ptr = *head;
    			while(ptr->p_next != NULL && (strcmp(ptr->p_next->nome,nuovo_campo->nome) < 0))
    				ptr = ptr->p_next;
    			nuovo_campo->p_next = ptr->p_next;
    			ptr->p_next = nuovo_campo;
    		}
    	}
    	else
    	{
    		printf("Memoria esurita\n");
    	}
    }
    
    
    void print_lista(Persona *pl)
    {
    	printf("\n\n");
    	printf("lista: ");
    	while (pl){
    		printf("%s\n", pl->nome);
    		pl = pl->p_next;
    	}
    	printf("\n\n");
    }
    
  • Re: Problema con lista lineare

    skynet ha scritto:


    prova questo
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct persona
    {
    	char nome[20];
    	short eta;
    	struct persona *p_next;
    }Persona;
    
    
    void inserisci_campo(Persona **);
    void print_lista(Persona *);
    
    int main ()
    {
    	int op, menu=100;
    	Persona *head = NULL;
    		
    	while (menu<=100)
    	{
    		puts("\n\n\n=======================");
    		puts("GESTIONE DI UNA LISTA");
    		puts("=======================\n\n");
    		puts("Selezionare l'operazione:\n");
    		puts("1=Visualizzare la lista");
    		puts("2=Inserire un elemento");
    		puts("3=eliminare un elemento");
    		scanf("%d",&op);
    
    		switch (op)
    		{
    			case 1: print_lista(head); break;
    			case 2 : inserisci_campo(&head); break;
    			break;
    		}
    	}
    }
    
    void inserisci_campo(Persona **head)
    {
    	Persona *nuovo_campo = (Persona *)calloc(1,sizeof(struct persona));
    	if(nuovo_campo != NULL)
    	{
    		printf("Inserisci nome:\t");
    		scanf("%s",nuovo_campo->nome);
    		printf("inserisci eta\':\t");
    		scanf("%d",&nuovo_campo->eta);
    		nuovo_campo->p_next = NULL;
    		if(*head == NULL)
    		{
    			*head = nuovo_campo;
    		}
    		else
    		{
    			Persona *ptr = *head;
    			while(ptr->p_next != NULL && (strcmp(ptr->p_next->nome,nuovo_campo->nome) < 0))
    				ptr = ptr->p_next;
    			nuovo_campo->p_next = ptr->p_next;
    			ptr->p_next = nuovo_campo;
    		}
    	}
    	else
    	{
    		printf("Memoria esurita\n");
    	}
    }
    
    
    void print_lista(Persona *pl)
    {
    	printf("\n\n");
    	printf("lista: ");
    	while (pl){
    		printf("%s\n", pl->nome);
    		pl = pl->p_next;
    	}
    	printf("\n\n");
    }
    
    si questo và...l'unico problema è che il primo elemento che si inserisce lo lascia sempre in testa alla lista, ma gli altri li ordina.
    Ora cmq lo devo modificare perchè l'esercizio mi chiede di creare le funzioni di inserimento ed eliminazione in testa e inserimento ed eliminazione in mezzo.
    grazie mille, sei troppo bravo
  • Re: Problema con lista lineare

    Intanto metti a posto l'inserimento. Non ho dedicato troppo tempo ma si può modificare così:
    
        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
    
        typedef struct persona
        {
           char nome[20];
           short eta;
           struct persona *p_next;
        }Persona;
    
    
        void inserisci_campo(Persona **);
        void print_lista(Persona *);
    
        int main ()
        {
           int op, menu=100;
           Persona *head = NULL;
              
           while (menu<=100)
           {
              puts("\n\n\n=======================");
              puts("GESTIONE DI UNA LISTA");
              puts("=======================\n\n");
              puts("Selezionare l'operazione:\n");
              puts("1=Visualizzare la lista");
              puts("2=Inserire un elemento");
              puts("3=eliminare un elemento");
              scanf("%d",&op);
    
              switch (op)
              {
                 case 1: print_lista(head); break;
                 case 2 : inserisci_campo(&head); break;
                 break;
              }
           }
        }
    
        void inserisci_campo(Persona **head)
        {
           Persona *nuovo_campo = (Persona *)calloc(1,sizeof(struct persona));
           if(nuovo_campo != NULL)
           {
              printf("Inserisci nome:\t");
              scanf("%s",nuovo_campo->nome);
              printf("inserisci eta\':\t");
              scanf("%d",&nuovo_campo->eta);
              nuovo_campo->p_next = NULL;
              if(*head == NULL)
              {
                 *head = nuovo_campo;
              }
              else
              { 
                 if(strcmp(head->nome,nuovo_campo->nome) > 0)
                 {
                      nuovo_campo->next = head;
                      head = nuovo_campo;
                 }
                 else
                 {
                     Persona *ptr = *head;
                     while(ptr->p_next != NULL && (strcmp(ptr->p_next->nome,nuovo_campo->nome) < 0))
                        ptr = ptr->p_next;
                     nuovo_campo->p_next = ptr->p_next;
                     ptr->p_next = nuovo_campo;
                 }
              }
           }
           else
           {
              printf("Memoria esurita\n");
           }
        }
    
    
        void print_lista(Persona *pl)
        {
           printf("\n\n");
           printf("lista: ");
           while (pl){
              printf("%s\n", pl->nome);
              pl = pl->p_next;
           }
           printf("\n\n");
        }
    
    
    L'eliminazione si lascia per esercizio allo studente
  • Re: Problema con lista lineare

    Mi dà errore la stringa
    if(strcmp(head->nome,nuovo_campo->nome) > 0)
    mi dice error; request for member 'nome' in something not a structure or uninon

    EDIT:risolto modificando così
    if(strcmp((*head)->nome,nuovo_campo->nome) > 0)
    essendo head puntatore a puntatore.

    Ho corretto anche sotto,
    if(strcmp((*head)->nome,nuovo_campo->nome) > 0)
                 {
                      nuovo_campo->p_next = head;
                      head = nuovo_campo;
                 }
    con
    if(strcmp((*head)->nome,nuovo_campo->nome) > 0)
                 {
                      nuovo_campo->p_next = (*head);
                      (*head) = nuovo_campo;
                 }
    Perchè appunto l'inserimento in testa non avveniva...ora mi cimento con le funzioni di eliminazione.
    Come dovrei fare a prendere in input da tastiera il nodo da eliminare? Non essendoci gli indici qui non sò come proseguire
  • Re: Problema con lista lineare

    Elimina in base al nome, quindi aspettati una stringa dall'utente. usa strcmp che ti deve tornare 0 se il nome è corretto.
  • Re: Problema con lista lineare

    Finito,implementata anche l'eliminazione, voglio sapere cosa ne pensi
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct persona
        {
           char nome[20];
           short eta;
           struct persona *p_next;
        }Persona;
    
    
    void inserisci_campo(Persona ** );
    void elimina_campo(Persona **, Persona ** , Persona ** , int , int );
    void print_lista(Persona * );
    
    void main ()
    {
       int i, op, menu=100, n, cont=0;
       Persona *head, *punt, *pred;
       head = NULL;
    
        while (menu<=100)
          {
              puts("\n\n\n=======================");
              puts("GESTIONE DI UNA LISTA");
              puts("=======================\n\n");
              puts("Selezionare l'operazione:\n");
              puts("1=Visualizzare la lista");
              puts("2=Inserire un elemento");
              puts("3=eliminare un elemento");
              scanf("%d",&op);
    
           switch (op)
              {
                 case 1 : print_lista(head); break;
                 case 2 : inserisci_campo(&head);
                          printf("Lista aggiornata:\n\n");
                          print_lista(head);
                          cont++; break;
                 case 3:  printf("Selezionare il numero di nodo da eliminare:\n");
                          print_lista(head);
                          scanf("%d",&n);
                          punt=head;
                          for (i=0;i<n-1;i++){
                            pred=punt;
                            punt=punt->p_next;}
                           elimina_campo(&punt,&head,&pred,n,cont);
                           printf("Lista aggiornata:\n\n");
                          print_lista(head);
    
              }
           }
        }
    
    void inserisci_campo(Persona **head)
     {
           Persona *nuovo_campo;
           nuovo_campo=calloc(1,sizeof(Persona));
           if(nuovo_campo != NULL)
           {
              printf("Inserisci nome:\t");
              scanf("%s",nuovo_campo->nome);
              printf("inserisci eta\':\t");
              scanf("%d",&nuovo_campo->eta);
              nuovo_campo->p_next = NULL;
              if(*head == NULL)
              {
                 *head = nuovo_campo;
              }
              else
              {
                 if(strcmp((*head)->nome,nuovo_campo->nome) > 0)
                 {
                      nuovo_campo->p_next = (*head);
                      (*head) = nuovo_campo;
                 }
                 else
                 {
                     Persona *ptr = *head;
                     while(ptr->p_next != NULL && (strcmp(ptr->p_next->nome,nuovo_campo->nome) < 0))
                     ptr = ptr->p_next;
                     nuovo_campo->p_next = ptr->p_next;
                     ptr->p_next = nuovo_campo;
    
                 }
              }
           }
           else
           {
              printf("Memoria esurita\n");
           }
     }
    void elimina_campo(Persona **p_punt, Persona **p_head, Persona **p_pred, int n, int cont)
    {
        if (n==1)
        {
            (*p_head)=(*p_head)->p_next;
        }
        else
        {
            if (n<cont)
            {
                (*p_pred)->p_next=(*p_punt)->p_next;
    
            }
            else
            {
                (*p_pred)->p_next=NULL;
            }
        }
    }
     void print_lista(Persona *pl)
     {
           int i=0;
           printf("\n\n");
           printf("lista:\n");
           while (pl){
              i++;
              printf("%d=%s\t%d\n", i , pl->nome, pl->eta);
              pl = pl->p_next;
           }
           printf("\n\n");
     }
    
  • Re: Problema con lista lineare

    Dov'è il free che elimina il campo? Non lo vedo nel listato. Poi ti servono davvero tutti sti puntatori?
    Se io inserisco un nodo che non esiste che succede? Il programma va in crash.
  • Re: Problema con lista lineare

    skynet ha scritto:


    dov'è il free che elimina il campo? Non lo vedo nel listato. Poi ti servono davvero tutti sti puntatori?
    Se io inserisco un nodo che non esiste che succede? Il programma va in crash.
    in che senso inserisci un nodo che non esiste? cioè vuoto sia di nome che di testo?
  • Re: Problema con lista lineare

    Eliminare un nodo:

    Inserisci il nodo da eliminare: utente inserisce 100 quando la lista ha magari 10 elementi. Il programma va in crash.
  • Re: Problema con lista lineare

    skynet ha scritto:


    Eliminare un nodo:

    Inserisci il nodo da eliminare: utente inserisce 100 quando la lista ha magari 10 elementi. Il programma va in crash.
    Giusto...
    Ho provato ad aggiungere un if nel main, cioè
    if (n>cont)
                        printf("Elemento inesistente");
              else
                      elimina_campo(&punt,&head,&pred,n,cont);
    dove cont è un contatore al numero di elementi, però mi và in crash comunque, come mai?
Devi accedere o registrarti per scrivere nel forum
28 risposte