IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

probleme liste simplement chainée (trie)


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2014
    Messages : 18
    Par défaut probleme liste simplement chainée (trie)
    j'ai un problème avec le trie d'une lste chainée a laquelle je peux ajouter des compte(nom,prenom) et la trier alphabétiquement après.
    je comprends pas pourquoi le code bloque quand ça atteint plus que 3 comptes .
    voici le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    #include<stdio.h>
    #include <string.h>
    #include <stdbool.h>
    #include <stdlib.h>
     
     int p=0;
    struct _date
    {
       int jour;
       int mois;
       int annee;
    };
     
    typedef struct cm
    {
      char nom[20];
      char prenom[20];
      struct _date date;
    }cmp;
     
    typedef struct p
    {
     cmp compte;
     struct p *next;
    }liste_compte;
     
    cmp saisircmp()
        {
         cmp c;
         printf("saisissez votre nom : ");scanf("%s",c.nom);
         printf("aisissez votre prenom : ");scanf("%s",c.prenom);
        /* printf("aisissez la date \n");
         printf("\t aisissez  le jour  : ");scanf("%d",&c.date.jour);
         printf("\t aisissez   le mois  : ");scanf("%d",&c.date.mois);
         printf("\t aisissez  le annee  : ");scanf("%d",&c.date.annee); */
     
         return c;
        }
     void enregistre(cmp *c)
        {
          FILE *fichier =NULL;
          fichier = fopen("daba.txt","a");
     
              fprintf(fichier,"\t\t\tinformation sur le  compte\n ");
              fprintf(fichier,"prenom : %s \n nom : %s \n",c->prenom,c->nom );
              fprintf(fichier," date : %d / %d / %d \n",c->date.jour,c->date.mois,c->date.annee );
          fclose(fichier);
        }
    void ajoutercmp(liste_compte **tete)
        {
          p++;
          liste_compte *nv=(liste_compte*)malloc(sizeof(liste_compte));
          nv->compte=saisircmp();
          /*enregistre(  &(nv->compte)  );*/
          nv->next=*tete;
          *tete=nv;
        }
    void afficher(liste_compte **tete)
        {
           liste_compte *temp=*tete;
          while(temp!=NULL )
          {
           printf("-----------\n") ;
           printf("prenom : %s \n nom : %s \n",temp->compte.prenom,temp->compte.nom );
          // printf(" date : %d / %d / %d \n",temp->compte.date.jour,temp->compte.date.mois,temp->compte.date.annee );
           temp=temp->next;
          }
        }
     
    void recherche (liste_compte **tete)
        {
         liste_compte *temp=*tete;char mot[20];
         scanf("%s",mot);
     
        while(temp!=NULL )
          {
             if (strcmp(temp->compte.nom,mot)== 0)
              {
                printf("information sur ce cmpte \n\tprenom : %s \n nom : %s \n",temp->compte.prenom,temp->compte.nom );
                printf(" \tdate : %d / %d / %d \n",temp->compte.date.jour,temp->compte.date.mois,temp->compte.date.annee );
              }
            temp=temp->next;
     
          }
     
        }
     
    void supcmp(liste_compte **tete)
        {
         liste_compte *temp,*temp1;char mot[20];bool b=false,p=false;temp=*tete;temp1=*tete;
         printf("entrer le nom du propriétaire du compte que vous voulez supprimer ");
         scanf("%s",mot);
         while(strcmp(temp->compte.nom,mot)!=0 && temp->next!=NULL)
         {     if(strcmp(temp->compte.nom,mot)==0) p=true;
              temp1=temp;
              temp=temp->next;b=true;
         }
          if (*tete ==NULL) exit(EXIT_FAILURE);
          else if(temp->next==NULL && b==1) {temp1->next=NULL;free(temp);printf("dernier\n");}    //dernier
          else if(strcmp(temp->compte.nom,mot)==0 && b==false)  //supr ala tete
              {*tete=temp->next;free(temp);printf("en tete\n");}
          else if(b && p)               // suppriemr au milieu
          {
             temp1->next=temp->next;
             free(temp);printf("au milieu\n");
          }
          else printf("ce compte n'existe pas ! \n") ;  //nexiste pas
     
        }
    void triercmp(liste_compte **tete)
        {
         liste_compte *temp1,*save,*tempo,*temp2;bool r=true;int u;
           for(;r;)
           {
               r=false ; u=p-1;
               printf("\n k=%d\n",u);
               temp1=*tete;
               temp2=temp1->next;save=*tete;
               printf("\n un tour \n");
               while(u--)
              {   printf("\n un tour \n");
                if( strcmp( temp1->compte.nom,temp2->compte.nom) >0 )
                {
                     if(temp1 == *tete )
                     {
                         printf("\n\t\t save = %s  t1= %s t2= %s   savetete \n",save->compte.nom,temp1->compte.nom,temp2->compte.nom);
                         *tete=temp2;tempo=temp2->next;
                          temp2->next=temp1;
                          temp1->next=tempo;
                     }
                     else if(temp2->next != NULL)
                     {
                         printf("\n\t\tsave  %s t1= %s t2= %s\n",save->compte.nom,temp1->compte.nom,temp2->compte.nom);
                         save->next=temp2;tempo=temp2->next;
                         temp2->next=temp1;
                         temp1->next=tempo;
                     }
                     else if( temp2->next==NULL)
                     {
                         save->next=temp2;
                         temp2->next=temp1;
                         temp1->next=NULL;
                     }
                     r=true ;
                }
                save=temp1;
                temp1=temp1->next;
                temp2=temp2->next;
              }
            }
        }
     void  main(void)
    {
          liste_compte *tete=NULL;
          int i,c,k=0;
            for(i=1;i<30;i++)
           {
             printf("__________________________________________\nentrer votre choix \n\t1 :ajouter un compte\n\t2 : afficher les comptes \n\t3 : rechercherr \n\t4 : supprimer\n\t5 : trier\n\t 6 : quitter\n");
             printf("\n entrer un nombre ");
             scanf("%d",&c);
             switch(c)
             {
              case 1: ajoutercmp(&tete);
                     break;
              case 2:afficher(&tete);
                     break ;
              case 3:
                     recherche(&tete) ;
                     break;
              case 4:
                    supcmp(&tete);
                     break;
              case 5:
                     triercmp(&tete);
                     break;
              case 6:
                     exit(EXIT_FAILURE);
                     break;
              default:
               ;
             }
           }
    }

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Ton exemple de code n'est pas minimal, et tes noms de structure et variables manquent de rigueur.
    Pas étonnant que tu aies du mal à t'y retrouver!
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 548
    Par défaut
    Bonjour
    En plus des remarques qui ont été dite, il faut revoir l'indentation des différentes instructions écrites.
    Évités d'ajouter des variables qui au final ne seront pas du tout utilisés.
    Prendre en compte les avertissements du compilateur et faire le nécessaire.
    Faire des saisies sécuriser des donnée.
    Revoir la fonction de recherche et l'adapté au mieux

    à bientôt

  4. #4
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    juste un extrait de ton code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void supcmp(liste_compte **tete)
        {
         liste_compte *temp,*temp1;char mot[20];bool b=false,p=false;temp=*tete;temp1=*tete;
    Il vaut franchement mieux écrire:
    voire même:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void supprimer_compte(liste_compte * *tete) {
         liste_compte *temp = *tete;
         liste_compte *temp1 = *tete;
         char mot[20];
         bool un_vrai_nom=false;
         bool un_autre_vrai_nom=false;

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2014
    Messages : 18
    Par défaut merci
    merci pour vos conseils sauf que vous avez pas encore saisi mon problème , je vais vous donner un petit bout de code que vous pouvez essayer pour comprendre mon problème car j'ai saisi ou vient mon problème sauf que je sais pas comment le résoudre dans ma fonction de trie est une technique de trie usuelle étant le trie par bulle , ça marche quand je mets 4/5 lettres(pour essayer) mais après ça bug . je vais vous donner le bout de code que vous pouvez essayer pour comprendre au mieux , car j'ai mis trois variable save qui aura la structure avant les deux lettre que je vais permuter , et temp1(la première structure) et temp2 la deuxième structure a permuter avec la première. voici le bout de code .
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    #include<stdio.h>
    #include <string.h>
    #include <stdbool.h>
    #include <stdlib.h>
     
     int p=0;
    struct _date
    {
       int jour;
       int mois;
       int annee;
    };
     
    typedef struct cm
    {
      char nom[20];
      char prenom[20];
      struct _date date;
    }cmp;
     
    typedef struct p
    {
     cmp compte;
     struct p *next;
    }liste_compte;
     
    cmp saisircmp()
        {
         cmp c;
         printf("saisissez votre nom : ");scanf("%s",c.nom);
       // printf("aisissez votre prenom : ");scanf("%s",c.prenom);
        /* printf("aisissez la date \n");
         printf("\t aisissez  le jour  : ");scanf("%d",&c.date.jour);
         printf("\t aisissez   le mois  : ");scanf("%d",&c.date.mois);
         printf("\t aisissez  le annee  : ");scanf("%d",&c.date.annee); */
     
         return c;
        }
    void ajoutercmp(liste_compte **tete)
        {
          p++;
          liste_compte *nv=(liste_compte*)malloc(sizeof(liste_compte));
          nv->compte=saisircmp();
          /*enregistre(  &(nv->compte)  );*/
          nv->next=*tete;
          *tete=nv;
        }
    void afficher(liste_compte **tete)
        {
           liste_compte *temp=*tete;
          while(temp!=NULL )
          {
           printf("-----------\n") ;
           printf("nom : %s \n",temp->compte.nom );
          /* printf("prenom : %s \n ",temp->compte.prenom ); */
          // printf(" date : %d / %d / %d \n",temp->compte.date.jour,temp->compte.date.mois,temp->compte.date.annee );
           temp=temp->next;
          }
        }
    void triercmp(liste_compte **tete)
        {
        liste_compte *temp1,*save,*tempo,*temp2;bool r=true;int i,k=0;
           for(;r;)
           {
               r=false ;k=0;
               temp1=*tete;
               temp2=temp1->next;save=*tete;
               printf("\n un tour \n");
               while(  temp2 != NULL  && temp1 != NULL)
              {
                 if( strcmp( temp1->compte.nom,temp2->compte.nom) >0 )
                {
                     if(temp1 == *tete )
                     {
                          /*printf("\n\t\t savetete  save = %s --------- t1= %s ----------- t2= %s    \n",save->compte.nom,temp1->compte.nom,temp2->compte.nom);
                         *tete=temp2;tempo=temp2->next;
                          temp2->next=temp1;
                          temp1->next=tempo;
                        r=true ;  */
                     }
                      else if( temp2->next!=NULL )
                     {
                         printf("\n\t\t milieu  save %s ---------t1= %s ---------t2= %s\n",save->compte.nom,temp1->compte.nom,temp2->compte.nom);
                         save->next=temp2;tempo=temp2->next;
                         temp2->next=temp1;
                         temp1->next=tempo;r=true;k++; if(k==5) {printf("ça suffit "); afficher(*tete);exit(EXIT_FAILURE);} ;
                     }
                     /*else if( temp2->next==NULL)
                     {
                      printf("\n\t\t a la fin  save :%s ------t1= %s ----------t2= %s\n",save->compte.nom,temp1->compte.nom,temp2->compte.nom);
                         save->next=temp2;
                         temp2->next=temp1;
                         temp1->next=NULL;
                         r=true ;
                     }   */
     
                }
                  save=temp1;
                  temp1=temp1->next;
                  temp2=temp2->next;
              }
            }
        }
     void  main(void)
    {
          liste_compte *tete=NULL;
          int i,c,k=0;
            for(i=1;i<30;i++)
           {
             printf("\n__________________________________________\nentrer votre choix \n\t1 :ajouter un compte\n\t2 : afficher les comptes \n\t3 : rechercherr \n\t4 : supprimer\n\t5 : trier\n\t 6 : quitter\n");
             printf("\n entrer un nombre ");
             scanf("%d",&c);
             switch(c)
             {
              case 1: ajoutercmp(&tete);
                     break;
              case 2:
                     triercmp(&tete);
                     break;
              case 6:
                     exit(EXIT_FAILURE);
                     break;
              default:
               ;
             }
           }
    }
    j'ai mis en commentaire le trie au début et a la fin car ils marches très bien , mais quand les deux lettres(noms) sont au milieu , c là ou vient le problème après qu'on ajoute plus que 5 noms

  6. #6
    Invité
    Invité(e)
    Par défaut
    Bonsoir,

    Tu pourrais éventuellement commencer par là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    >gcc -Wall -Wextra main.c -c
    main.c: In function 'triercmp':
    main.c:86:94: warning: passing argument 1 of 'afficher' from incompatible pointer type
                          temp1->next=tempo;r=true;k++; if(k==5) {printf("ça suffit "); afficher(*tete);exit(EXIT_FAILURE);} ;
                                                                                                 ^
    main.c:48:6: note: expected 'struct liste_compte **' but argument is of type 'struct liste_compte *'
     void afficher(liste_compte **tete)
          ^
    main.c:62:61: warning: unused variable 'i' [-Wunused-variable]
         liste_compte *temp1,*save,*tempo,*temp2;bool r=true;int i,k=0;
                                                                 ^
    main.c: At top level:
    main.c:104:8: warning: return type of 'main' is not 'int' [-Wmain]
      void  main(void)
            ^
    main.c: In function 'main':
    main.c:107:15: warning: unused variable 'k' [-Wunused-variable]
           int i,c,k=0;
                   ^
    Et comme te l'a suggéré leternel, ne mets qu'une seule instruction par ligne, tu rendras la lecture de ton code plus facile et agréable.
    N'oublie pas non plus de libérer la mémoire que tu alloues.

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 830
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 830
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par débutant_01 Voir le message
    merci pour vos conseils sauf que vous avez pas encore saisi mon problème , je vais vous donner un petit bout de code que vous pouvez essayer pour comprendre mon problème car j'ai saisi ou vient mon problème sauf que je sais pas comment le résoudre dans ma fonction de trie est une technique de trie usuelle étant le trie par bulle , ça marche quand je mets 4/5 lettres(pour essayer) mais après ça bug .
    Bonjour

    Je crois que c'est toi qui n'a pas saisi le concept de liste chainée
    une liste chainée offre l'avantage de pouvoir insérer un maillon n'importe où. Il est donc possible d'avoir une liste toujours triée. Donc "trier" une liste (avec tout le temps que ça prend) devient alors inutile. Et si la liste doit-être triée sur plusieurs critères (tri par noms, tri par prénoms), alors il est tout à fait possible de mettre un pointeur par critère (pointeur du nom suivant, pointeur du prénom suivant).
    Exemple
    • maillon 10: Alexandre Anatole
    • maillon 20: Jean Valjean
    • maillon 30: Cécile Zixmul


    Alors pour le critère "nom" le chainage sera 10, 20, 30, NULL et pour le critère "prénom" le chainage sera 10, 30, 20, NULL. Ca demande un peu de rigueur effectivement mais vu ton code (bien découpé) tu ne devrais pas avoir de mal

    Ensuite quand des membres habitués et qui ont une valeur reconnue (ou qui commence à le devenir) te disent que tu as mal commencé, ce n'est pas la peine de dire "oui mais vous n'avez rien compris" parce qu'ils ont parfaitement compris ton problème mais que dans leur monde, ce problème n'aurait jamais eu lieu vu qu'ils ne l'auraient jamais abordé de cette façon.

    Perso je rajouterais quelques remarques
    • nomme tes structures "s_xxx" et tes types "t_xxx". Ca t'évitera de galérer avec tes typedef struct cm { ... } cmp...
    • rajoute un type dédié à ta liste elle-même. A ce propos, ton type "liste_compte" n'est absolument pas un type de liste mais un type de maillon. Donc rajoute un type dédié à la liste elle-même. Cet élément pourra alors contenir le pointeur sur le premier maillon, éventuellement la longueur de la liste, et si tu as besoin d'avoir plusieurs critères de tris, le rajout des autres pointeurs en sera facilité. Et surtout ça t'évitera ces **tete vu que la fonction d'insertion, recevant un simple pointeur sur la liste elle-même, pourra alors modifier facilement n'importe quel maillon y compris le premier.
    • main() n'est pas de type void


    Donc écoute les conseils des (je ne vais pas dire "pros" ça fait "m'as-tu-vu?") mais au-moins "habitués. Un code c'est comme une maison: il faut poser de bonnes bases bien solides pour éviter qu'elle s'écroule 6 mois plus tard. Déjà t'as bien pensé à découper de façon plutôt sensée donc je pense que t'es déjà câblé pour accepter nos conseils (parce que si je ne le pensais pas, jamais j'aurais perdu 15 minutes à taper tout ce fourbi).
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. Insertion d'un élément dans une liste simplement chainée triée (croissante)
    Par vayouva dans le forum Algorithmes et structures de données
    Réponses: 1
    Dernier message: 14/11/2014, 09h29
  2. probleme liste doublement chaineés
    Par sba1990 dans le forum Algorithmes et structures de données
    Réponses: 1
    Dernier message: 30/03/2008, 16h13
  3. Réponses: 3
    Dernier message: 25/10/2006, 19h08
  4. Liste simplement chainée
    Par sorry60 dans le forum C
    Réponses: 54
    Dernier message: 29/11/2005, 22h05
  5. Probleme liste simplement chaînée
    Par sorry60 dans le forum C
    Réponses: 23
    Dernier message: 19/11/2005, 20h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo