[RISOLTO] Inserimento in lista ordinata alfabeticamente [C]

di il
41 risposte

41 Risposte - Pagina 2

  • Re: [RISOLTO] Inserimento in lista ordinata alfabeticamente [C]

    Nippolo ha scritto:


    Ok, ma non vuoi proprio provarci a tradurre quella frase in codice?
    Magari il problema sono le stringhe, quindi facciamo un altro esempio... hai delle coppie di numeri che rappresentano mese e anno, sei in grado di ordinare le date? Mi spiego meglio, ipotizziamo di avere la seguente struct
    struct data
    {
        int mese;
        int anno;
    }
    Sei in grado di completare la seguente funzione?
    void fun(data data1, data data2)
    {
        if(...)
        {
            printf("data1 viene dopo data2!");
        }
    }
    Codice del tuo esempio:
    void fun(data dat1, data data2)
    {
        if(data1.anno > data2.anno || (data1.anno == data2.anno && data1.giorno > data2.giorno))
        {
            printf("Data1 viene dopo Data2);
        }
    }
    Quindi la condizione per verificare se persona1>persona2 :
    while(corr!= NULL && ((strcmp(persona.cognome,corr->persona.cognome)>0)||(strcmp(persona.cognome,corr->persona.cognome)==0)&&strcmp(persona.nome,corr->persona.nome)>0))
      {
        prec=corr;
        corr=corr->next;
      }
      nuovo=(t_nodo *)malloc(sizeof(t_nodo));
      assert(nuovo!=NULL);
      nuovo->persona=persona;
      if(prec==NULL)
      {
        nuovo->next=lista;
        lista=nuovo;
        return lista;
      }
      else
      {
        prec->next=nuovo;
        nuovo->next=corr;
        return lista;
      }
    FUNZIONA!!

    Nippolo ha scritto:


    Pensavo che la variabile "corr" fosse necessaria per scorrere la lista...
    Perchè la ritenevi necessaria?
    Quindi si è possibile non usare la variabile "corr"...
    Ti sei fatto un'idea del perchè?
    Se non uso la variabile corr, dopo che stampa però mi esce dal programma. Oppure mi sbagliava la formattazione della stampa.
    Comunque concordavo con te sul fatto di poter non usare la varabile "corr" in quanto tramite la variabile "Lista" punto alla testa della lista e posso tranquillamente scorrere senza dovere tener conto della testa. Ho capito bene?
    Solo che se non uso la variabile di appoggio "corr" mi sbaglia la stampa.

    Grazie mille per la pazienza comunque!
  • Re: [RISOLTO] Inserimento in lista ordinata alfabeticamente [C]

    Di niente!

    Tutto il discorso sulla funzione stampa si basa sul fatto che il passaggio di un argomento ad una funzione avviene per copia, quindi non c'è alcun problema se il puntatore passato alla funzione stampa_lista() viene modificato.

    Per quanto riguarda il fatto che senza la variabile "corr" il programma non funziona bene, sinceramente mi sembra strano... potresti postare il codice completo? Così ho la possibilità di testarlo.
  • Re: [RISOLTO] Inserimento in lista ordinata alfabeticamente [C]

    Nippolo ha scritto:



    Per quanto riguarda il fatto che senza la variabile "corr" il programma non funziona bene, sinceramente mi sembra strano... potresti postare il codice completo? Così ho la possibilità di testarlo.
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
    #define MAX 30
    //--------------------------------------------------------------------------------------------------
    //------------------------------------------------STRUTTURE DATI------------------------------------
    //--------------------------------------------------------------------------------------------------
    
    struct s_persona
    {
      char cognome[MAX];
      char nome[MAX];
    };
    typedef struct s_persona t_persona;
    
    struct s_nodo
    {
      t_persona persona;
      struct s_nodo *next;
    };
    typedef struct s_nodo t_nodo;
    typedef t_nodo *t_lista;
    
    //--------------------------------------------------------------------------------------------------
    //-------------------------------------------PROTOTIPI FUNZIONI------------------------------
    //--------------------------------------------------------------------------------------------------
    t_persona aggiungi_persona();
    t_lista inserimento_lista(t_lista lista,t_persona persona);
    void stampa_lista(t_lista lista);
    t_nodo *cerca_persona(t_lista lista, char *cognome, char *nome);
    t_lista cancella_persona(t_lista lista, char *cognome, char *nome);
    t_lista cancella_lista(t_lista lista);
    
    //--------------------------------------------------------------------------------------------------
    //------------------------------------------------MAIN--------------------------------------------
    //--------------------------------------------------------------------------------------------------
    int main()
    {
      int scelta,i,n_persone;
      char cognome[MAX], nome[MAX];
      t_lista lista;    //Creo una variabile 'lista' di tipo 't_lista'
      t_persona persona;    //Creo una variabile 'persona' di tipo 't_persona'
      t_nodo *persona_cercata;
      //**INIZIALIZZO UNA LISTA VUOTA**
      lista=NULL;
      do
      {
        system("CLS");
        printf("\n**MENU ESERCIZIO LISTE**\n");
        printf("1. Inserisci Persona nella Lista\n");
        printf("2. Stampa Lista\n");
        printf("3. Cerca Persona nella Lista\n");
        printf("4. Cencella Persona dalla Lista\n");
        printf("5. Cancella Lista\n");
        printf("6. Esci\n\n");
        printf("Scegli un'opzione del menù: ");
        scanf("%d",&scelta);
        switch(scelta)
        {
          case 1:
            system("CLS");
            printf("\n**INSERIMENTO PERSONA IN LISTA**\n");
            printf("Quante Persone vuoi inserire in Lista? ");
            scanf("%d",&n_persone);
            for(i=0;i<n_persone;i++)
            {
              persona=aggiungi_persona();
              lista=inserimento_lista(lista,persona);
            }
            scelta=7;
            printf("\n");
            system("PAUSE");
            break;
          case 2:
            system("CLS");
            printf("\n**STAMPA PERSONE IN LISTA**\n");
            stampa_lista(lista);
            scelta=7;
            printf("\n");
            system("PAUSE");
            break;
          case 3:
            system("CLS");
            printf("\n**CERCA PERSONE NELLA LISTA**\n");
            printf("Inserire Cognome e Nome della persona da cercare:\n");
            fflush(stdin);
            printf("\nCognome: ");
            gets(cognome);
            printf("\nNome: ");
            gets(nome);
            fflush(stdin);
            persona_cercata=cerca_persona(lista,cognome,nome);
            if(persona_cercata!=NULL)
            {
              printf("\nPersona presente nella Lista\n");
              scelta=7;
              system("PAUSE");
              break;
            }
            else
            {
              printf("\nPersona NON presente in Lista\n");
              scelta=7;
              system("PAUSE");
              break;
            }
          case 4:
            system("CLS");
            printf("\n**CANCELLA PERSONA DALLA LISTA**\n");
            printf("Inserire Cognome e Nome della persona da eliminare:\n");
            fflush(stdin);
            printf("Cognome: ");
            gets(cognome);
            printf("Nome: ");
            gets(nome);
            fflush(stdin);
            lista=cancella_persona(lista,cognome,nome);
            scelta=7;
            system("PAUSE");
            break;
          case 5:
            system("CLS");
            printf("\n**ELIMINA LISTA**\n");
            lista=cancella_lista(lista);
            assert(lista==NULL);
            printf("Lista cancellata con successo\n");
            scelta=7;
            system("PAUSE");
            break;
          default:
            printf("!ERRORE! -> Scelta non disponibile nel menù.\n\n");
            system("PAUSE");
            break;
        }
      }while(scelta<1 || scelta>6);
    }
    
    //--------------------------------------------------------------------------------------------------
    //----------------------------------------------DEFINIZIONE FUNZIONI------------------------
    //--------------------------------------------------------------------------------------------------
    
    //FUNZIONE AGGIUNGI PERSONA IN LISTA
    t_persona aggiungi_persona()
    {
      system("CLS");
      t_persona persona;
      fflush(stdin);
      printf("Inserisci Cognome: ");
      gets(persona.cognome);
      printf("Inserisci Nome: ");
      gets(persona.nome);
      fflush(stdin);
      return persona;
    }
    
    //FUNZIONE INSERIMENTO ORDINATO IN LISTA
    t_lista inserimento_lista(t_lista lista,t_persona persona)
    {
      int ctrl_1=1;
      int ctrl_2=1;
      t_lista prec,corr,nuovo;
      prec=NULL;
      corr=lista;
    
      while(corr!= NULL && ((strcmp(persona.cognome,corr->persona.cognome)>0)||
      (strcmp(persona.cognome,corr->persona.cognome)==0)&&strcmp(persona.nome,corr->persona.nome)>0))
      {
        prec=corr;
        corr=corr->next;
      }
      nuovo=(t_nodo *)malloc(sizeof(t_nodo));
      assert(nuovo!=NULL);
      nuovo->persona=persona;
      if(prec==NULL)
      {
        nuovo->next=lista;
        lista=nuovo;
        return lista;
      }
      else
      {
        prec->next=nuovo;
        nuovo->next=corr;
        return lista;
      }
    }
    
    //FUNZIONE STAMPA LISTA
    void stampa_lista(t_lista lista)
    {
      t_lista corr; //Variabile per scorrere la lista
      corr=lista;
      while(corr!=NULL)
      {
        printf("\n%s %s",corr->persona.cognome,corr->persona.nome);
        corr=corr->next;
      }
      return;
    }
    
    //FUNZIONE CERCA PERSONA NELLA LISTA (Momentaneamente passando sia cognome e nome)
    t_nodo *cerca_persona(t_lista lista, char *cognome, char *nome)
    {
      int ctrl_1=1;
      int ctrl_2=1;
      t_nodo *corr;
      corr=lista;
      //Cerco la posizione della Persona all'interno della Lista
      while(corr!=NULL && (ctrl_1=strcmp(cognome,corr->persona.cognome))>0)
      {
        corr=corr->next;
      }
      if(ctrl_1==0)
      {
        while(corr!=NULL && (ctrl_2=strcmp(nome,corr->persona.nome))>0)
        {
          corr=corr->next;
        }
      }
      if(ctrl_1==0 && ctrl_2==0)
        return corr;
      else
        return NULL;
    }
    
    //FUNZIONE CANCELLA PERSONA DALLA LISTA
    t_lista cancella_persona(t_lista lista, char *cognome, char *nome)
    {
      int ctrl_1=1;
      int ctrl_2=1;
      t_lista prec,corr;
      prec=NULL;
      corr=lista;
      //Ricerca Posizione
      while(corr!=NULL && (ctrl_1=strcmp(cognome,corr->persona.cognome))>0)
      {
        prec=corr;
        corr=corr->next;
      }
      if(ctrl_1==0)
      {
        while(corr!=NULL &&(ctrl_2=strcmp(nome,corr->persona.nome))>0)
        {
          prec=corr;
          corr=corr->next;
        }
      }
      if(ctrl_1==0 && ctrl_2==0)
      {
        if(prec==NULL)
        {
          lista=corr->next;
        }
        else
        {
          prec->next=corr->next;
        }
        free(corr);
        printf("Persona eliminata con successo\n");
        return lista;
      }
      else
      {
        printf("Persona non presente in lista");
        return lista;
      }
    
    }
    
    //FUNZIONE CANCELLA LISTA
    t_lista cancella_lista(t_lista lista)
    {
      t_lista corr,succ;
      corr=lista;
      while(corr!=NULL)
      {
        succ=corr->next;
        free(corr);
        corr=corr->next;
        corr=succ;
      }
      return NULL;
    }
    
    Ora però vorrei modificare la struttura dati, come vedrai dal codice la struttura dati è composta come segue:
    struct s_persona
    {
      char cognome[MAX];
      char nome[MAX];
    };
    typedef struct s_persona t_persona;
    
    struct s_nodo
    {
      t_persona persona;
      struct s_nodo *next;
    };
    typedef struct s_nodo t_nodo;
    typedef t_nodo *t_lista;
    
    Invece adesso ho implementato un struttura dati nel modo seguente:
    typedef struct s_persona
    {
      char cognome[MAX];
      char nome[MAX];
      struct s_persona *next;
    }persona;
    Ma sbaglio qualcosa mi sa, perchè nello stampare la lista accade:
    1) Stampa il primo inserito all'infinito o esce dal programma
    2) Stampa l'ultimo inserito all'infinito o esce dal programma
    3) Stampa il primo della lista all'infinito o esce dal programma
    Sbaglio sicuramente qualcosa nell'ordinare la lista e nell'utilizzo dei puntatori probabilmente. Ci smanetto un pò e in caso ti chiedo aiuto
  • Re: [RISOLTO] Inserimento in lista ordinata alfabeticamente [C]

    Poi mi guardo meglio il codice, cmq volevo farti sapere che la funzione stampa funziona correttamente anche senza la variabile "corr".
  • Re: [RISOLTO] Inserimento in lista ordinata alfabeticamente [C]

    Ci ho riprovato anche io, ora funziona. Non so perchè ma ieri mi dava questo problema, forse l'ora tarda mi avrà fatto combinare qualche guaio
  • Re: [RISOLTO] Inserimento in lista ordinata alfabeticamente [C]

    Probabile!

    Per essere sicuro che tu abbia capito cosa intendessi dire quando ho parlato di passaggio per copia, ti faccio una domanda:
    se inserimento_lista() avesse come tipo di ritorno void, quale dovrebbe essere il prototipo della funzione?
  • Re: [RISOLTO] Inserimento in lista ordinata alfabeticamente [C]

    Sarebbe stata "void inserimento_lista(t_lista *lista, t_persona *persona)" ?
    Però ammetto di non essere molto certo a riguardo perchè ancora faccio un pò di confusione a riguardo.
    Ovvero non mi è molto il perchè e quando passare un argomento puntatore o meno, diciamo che ci sto andando ad intuito. Tant'è che nel modificare la struttura dati e a riscrivere il codice sto avendo qualche difficoltà.

    EDIT:
    Guardando altri compiti svolti nell'inserimento in lista ho visto anche un prototipo del genere:
    void inserisciContatto(contatto_t**head,contatto_t *p){
      contatto_t *succ=*head,*prec=*head;
      ...
      ...
      ...
      }
    Perchè e quando utilizzare un puntatore di puntatore?
  • Re: [RISOLTO] Inserimento in lista ordinata alfabeticamente [C]

    In C il passaggio di un parametro ad una funzione avviene sempre per valore.
    Quando esegue la chiamata di una funzione, il programma costruisce una copia di ogni argomento, creando delle variabili locali nell'ambito della funzione; ciò significa che tutte le modifiche, fatte dalla funzione al valore di un argomento, hanno effetto soltanto nell'ambito della funzione stessa.
    Se invece si vuole che le modifiche apportate dalla funzione all'argomento non vadano perdute, bisogna modificare l'argomento attraverso il suo indirizzo di memoria. Ciò significa che in C, per simulare un passaggio per riferimento, bisogna passare alla funzione un puntatore di ordine superiore rispetto alla variabile che si vuole modificare attraverso la funzione.

    Esempi:
    - variabile di tipo int ==> argomento di tipo int*;
    - variabile di tipo char* ==> argomento di tipo char**;
    - variabile di tipo float*** ==> argomento di tipo float****.

    Spero di aver chiarito i tuoi dubbi e che adesso tu abbia compreso perchè la variabile "corr" nella funzione stampa_lista() era inutile!
  • Re: [RISOLTO] Inserimento in lista ordinata alfabeticamente [C]

    Ti rompo ancora un pò le scatole Come ti dicevo sto provando a riscrivere il codice modificando la struttura dati come segue:
    typedef struct s_persona
    {
      char cognome[MAX];
      char nome[MAX];
      struct s_persona *next;
    }persona;
    
    Ho fatto 2 implementazioni del codice, la prima ovviamente non funzionava, la seconda, dopo aver smanettato un pò è funzionante. L'unico problema è che non ho ben chiaro il motivo del perchè facendo alcune modifiche l'inserimento e l'ordinamento funziona correttamente nel secondo codice.
    Ti posto di seguito le due diverse implementazioni:

    CODICE FUNZIONANTE:
    int main()
    {
      persona *head;
      head=NULL;
      int dim,i;
      printf("\nQuante persone vuoi inserire? ");
      scanf("%d",&dim);
      for(i=0;i<dim;i++)
      {
        nuova_persona(&head);
      }
    
      stampa_lista(head);
      //system("PAUSE");
    
      return 0;
    }
    
    //-------------------------------------------------------------------------------------------
    //--------------------------------------DEFINIZIONE FUNZIONI---------------------------------
    //-------------------------------------------------------------------------------------------
    
    void nuova_persona(persona **head)
    {
    
      persona *nuova_persona=NULL;
      nuova_persona=(persona* )malloc(sizeof(persona));
      assert(nuova_persona!=NULL);
      fflush(stdin);
      printf("\nCognome: ");
      gets(nuova_persona->cognome);
      printf("\nNome: ");
      gets(nuova_persona->nome);
      fflush(stdin);
      inserisci_persona(head,nuova_persona);
    
    }
    
    void inserisci_persona(persona **head, persona *nuova_persona)
    {
      persona *prec=*head,*corr=*head;
      while(corr!=NULL && ((strcmp(nuova_persona->cognome,corr->cognome)>0)||
      (strcmp(nuova_persona->cognome,corr->cognome)==0) && strcmp(nuova_persona->nome,corr->nome)>0))
      {
        prec=corr;
        corr=corr->next;
      }
      if(corr==*head)
      {
        printf("CORR==HEAD");
        *head=nuova_persona;
        nuova_persona->next=corr;
        return;
      }
      else if(corr==NULL)
      {
        printf("CORR==NULL");
        prec->next=nuova_persona;
        nuova_persona->next=NULL;
        return;
      }
      else
      {
        printf("CORR!=NULL");
        prec->next=nuova_persona;
        nuova_persona->next=corr;
        return;
      }
    }
    
    void stampa_lista(persona *head)
    {
      while(head!=NULL)
      {
        printf("\n%s %s",head->cognome,head->nome);
        head=head->next;
      }
      return;
    }

    CODICE NON FUNZIONANTE:
    int main()
    {
      persona *head=NULL;
      nuova_persona(&head);
      stampa_lista(head);
      return 0;
    }
    //-------------------------------------------------------------------------------------------
    //--------------------------------------DEFINIZIONE FUNZIONI---------------------------------
    //-------------------------------------------------------------------------------------------
    
    void nuova_persona(persona **head)
    {
      int i,dim;
      persona *nuova_persona=NULL;
      nuova_persona=(persona *)malloc(sizeof(persona));
      printf("Numero di persone da inserire in lista: ");
      scanf("%d",&dim);
      for(i=0;i<dim;i++)
      {
        fflush(stdin);
        printf("\nCognome: ");
        gets(nuova_persona->cognome);
        printf("\nNome: ");
        gets(nuova_persona->nome);
        fflush(stdin);
        inserisci_persona(head,nuova_persona);
      }
      return;
    }
    
    void inserisci_persona(persona **head, persona *nuova_persona)
    {
      persona *prec=*head,*corr=*head;
      while(corr!=NULL && ((strcmp(nuova_persona->cognome,corr->cognome)>0)||
      (strcmp(nuova_persona->cognome,corr->cognome)==0) && strcmp(nuova_persona->nome,corr->nome)>0))
      {
        prec=corr;
        corr=corr->next;
      }
      if(corr==*head)
      {
        printf("CORR==HEAD");
        *head=nuova_persona;
        nuova_persona->next=corr;
        return;
      }
      else if(corr==NULL)
      {
        printf("CORR==NULL");
        prec->next=nuova_persona;
        nuova_persona->next=NULL;
        return;
      }
      else
      {
        printf("CORR!=NULL");
        prec->next=nuova_persona;
        nuova_persona->next=corr;
        return;
      }
    }
    
    void stampa_lista(persona *head)
    {
      while(head!=NULL)
      {
        printf("\n%s %s",head->cognome,head->nome);
        head=head->next;
      }
      return;
    }
    Il problema dell'ultimo codice è che mi inserisce sempre in testa e stampa al'infinito l'ultimo elemento inserito.

    EDIT OFFTOPIC: Sto usando un editor di testo per scrivere il codice, ATOM. Quando compilo, che sia dal terminale di ATOM o dal terminale di Windows, sia la compilazione che l'avvio del file eseguibile sono molto lenti rispetto a quando eseguivo i medesimi passaggi su Ubuntu. Sai il perchè?
  • Re: [RISOLTO] Inserimento in lista ordinata alfabeticamente [C]

    Mi limito a commentare il codice non funzionante:
    - avevi creato una versione funzionante della funzione inserisci_persona(), perchè l'hai stravolta nuovamente?
    - nella funzione nuova_persona() quanti nuovi nodi/persone crei?
  • Re: [RISOLTO] Inserimento in lista ordinata alfabeticamente [C]

    L'ho modificata per provare a riscriverlo in modo diverso per sperimentare un altro codice e vedere se fosse funzionante. Non ho capito la tua domanda però
    Volevo fare in modo di inserire una nuova persona da due "funzioni concatenate" esterne al main
  • Re: [RISOLTO] Inserimento in lista ordinata alfabeticamente [C]

    Quante volte viene eseguita la seguente riga di codice?

    nuova_persona=(persona *)malloc(sizeof(persona));
  • Re: [RISOLTO] Inserimento in lista ordinata alfabeticamente [C]

    Viene eseguita ogni volta che viene inserita una persona. Che sia una o 10 in una volta. E' sbagliato?
    EDIT: In realtà questo è stato fatto nel codice funzionante. Quindi è questo l'errore?
  • Re: [RISOLTO] Inserimento in lista ordinata alfabeticamente [C]

    Quindi è questo l'errore?
    Non so se è l'unico però!
    Per esempio la funzione inserisci_persona(), visto che sei in possesso di una sua versione più semplice e sicuramente funzionante, non l'ho controllata.
  • Re: [RISOLTO] Inserimento in lista ordinata alfabeticamente [C]

    Scusami se ti rispondo solo ora, ma ho avuto giorni di febbre alle spalle.
    Ti volevo fare un'altra domanda, sto avendo qualche difficoltà nella funziona "cerca_persona"

    FUNZIONE CERCA_PERSONA:
    
    persona *cerca_persona(persona *head, char *cognome, char *nome)
    {
      int ctrl_1=1,ctrl_2=1;
      while(head!=NULL && ((ctrl_1=strcmp(cognome, head->cognome)>0)||
      (ctrl_1=strcmp(cognome,head->cognome)==0) && (ctrl_2=strcmp(nome,head->nome)>0)))
      {
        head=head->next;
      }
      if(ctrl_1==0 && ctrl_2==0)
        return head;
      else
        return NULL;
    }
    
    
    In questo codice proprio non ho idea di cosa sto sbagliando. Perchè sto usando lo stesso while dell'inserimento che dovrebbe essere il medesimo anche per la ricerca della persona no?
Devi accedere o registrarti per scrivere nel forum
41 risposte