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 :

tri et liste chainée double


Sujet :

C

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 19
    Par défaut tri et liste chainée double
    Bonjour à tous,

    Je dois faire un programme qui trie une liste chainée double selont différents criteres. Pour commencer j'ai décidé de ne classer la liste chainnée que par nom.

    Malheureusement je n'ai pas le résultat escompté.
    Au moment de l'affichage, cela m'affiche le une ligne à l'infini.

    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
     
     
    LISTE *tri_insertion(LISTE *liste,char choix)
    {
            LISTE *liste_triee; //liste toujours triée
            ENTREE *tmp;
            ENTREE *courant;
            liste_triee=creer_liste();
            while((liste->t)>1)
            {
                tmp=liste->first->next;
                courant=liste->first;
                while(courant!=NULL)
                {
                    if(strcmp(courant->nom,tmp->nom)<0)
                    {
                        tmp=courant;
                    }
                    courant=courant->next;
                }
     
                if(tmp->previous==NULL)
                {
                    liste->first=tmp->next;
                }
                else
                {
                    if(tmp->next==NULL)
                    {
                        tmp->previous->next=NULL;
                    }
                    else
                    {
                        tmp->previous->next=tmp->next;
                        tmp->next->previous=tmp->previous;
                    }
                }
                ajoute_entree(tmp,liste_triee);
                liste->t--;
            }
            ajoute_entree(liste->first,liste_triee);
            return liste_triee;
    }

    et la fonction ajoute_entree :

    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
     
    void ajoute_entree(ENTREE *entree, LISTE *liste) // ajoute une entree à la fin d'une liste initialisee ou existante (cfr. creer_liste())
    {
        //  (ne manipule pas les donnees).
        entree->previous=NULL;
        entree->next=NULL;
        if(liste->t==0)
        {
            liste->first=entree;
            entree->previous=NULL;
        }
        else
        {
            ENTREE *courant;
            ENTREE *previous;
            courant=liste->first;
            previous=liste->first;
            while(courant->next!=NULL)
            {
                courant=courant->next;
                if(courant->next==NULL)
                {
                    previous=courant;
                }
            }
            courant->next=entree;
            entree->previous=previous;
        }
        liste->t++;
    }
    J'ai refait l'exercice en algorithme sur une feuille et ca m'a l'air bon donc je comprends pas où est mon érreur...
    merci de votre aide...

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Bonjour,

    Ligne 27 : entree->previous=courant; ?

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 19
    Par défaut
    C'est vrai que j'ai mis une condition pour rien ..^^

    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
     
    void ajoute_entree(ENTREE *entree, LISTE *liste) // ajoute une entree à la fin d'une liste initialisee ou existante (cfr. creer_liste())
    {
        //  (ne manipule pas les donnees).
        entree->previous=NULL;
        entree->next=NULL;
        if(liste->t==0)
        {
            liste->first=entree;
            entree->previous=NULL;
        }
        else
        {
            ENTREE *courant;
            courant=liste->first;
            while(courant->next!=NULL)
            {
                courant=courant->next;
            }
            courant->next=entree;
            entree->previous=courant;
        }
        liste->t++;
    }
    .. C'est mieux comme ca , mais ca ne résout pas mon problème

  4. #4
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 19
    Par défaut help
    Personne ne peut m'aider ?

  5. #5
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    J'ai du mal à voir l'intérêt de choix.

    il est difficile de donner des explications sans tes structures.

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 19
    Par défaut
    Sorry ce n'est pas très clair, en fait le parrametre choix ne sert à rien , je comptais l'implémenter après.

    En fait les structures ont peu d'importance ici car je ne travaille qu'avec entree->nom pour commencer.

    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
     
    typedef struct entree
    {
        char nom[30];
        char prenom[20];
        char initiales[6];
        char mail[30];
        char tel[20];
        char classe[20];
        struct entree *next;
        struct entree *previous;
    } ENTREE;
     
    typedef struct liste
    {
        int t;
        struct entree *first;
    } LISTE;

  7. #7
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    Ok, il y a une fonction géniale permettant de faire cela assez rapidement.

    1) Tu crées une fonction de comparaison

    Quelquechose du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    static int compare (void const *a, void const *b)
    {
       /* definir des pointeurs type's et initialise's
          avec les parametres */
       char const *const *pa = a;
       char const *const *pb = b;
     
       /* evaluer et retourner l'etat de l'evaluation (tri croissant) */
       return strcmp (*pa, *pb);
    }
    2) Tu utilises qsort dont le prototype est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void qsort (void *tableau
                , size_t nb_elem
                , size_t taille_elem
                , int (*compare) (void const *a, void const *b));
    qsort est une fonction qui permet de tout trier, y compris les chaînes de caractères.

    En continuant sur l'exemple ça donnerait

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    qsort (tab, sizeof tab / sizeof *tab, sizeof *tab, compare);

  8. #8
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 19
    Par défaut
    Ca c'est une solution avec des tableaux, je dois garder ma liste chainée.
    Il s'agit d'un exercice pour lécole etje dois le faire à l'aide de liste chainée, dailleurs après je vais implémenter un choix de critere selon lequel on veut effectuer le tri (nom, prenom ,...)

  9. #9
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 19
    Par défaut résolu !
    J'ai fini par refaire entrièrement la fonction de tri en la sous-divisant en sous-fonctions pour être sur de ne pas me tromper et pour faciliter un éventuel débugage et ...miracle , cela tourne très bien.

    Voiçi le code si ca intéresse quelqu'un :


    Les structures :
    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
     
    typedef struct entree
    {
        char nom[30];
        char prenom[20];
        char initiales[6];
        char mail[30];
        char tel[20];
        char classe[20];
        struct entree *next;
        struct entree *previous;
    } ENTREE;
     
    typedef struct liste
    {
        int t;
        struct entree *first;
    } LISTE;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    LISTE *creer_liste()
    {
        LISTE *n_liste = malloc(sizeof(LISTE));
        n_liste->t=0;
        n_liste->first=NULL;
        return n_liste;
    }
    La fonction ajoute_entree -> qui n'a pas bougé (cela fonctionnait déjà avant)

    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
     
    void ajoute_entree(ENTREE *entree, LISTE *liste) // ajoute une entree à la fin d'une liste initialisee ou existante (cfr. creer_liste())
    {
        //  (ne manipule pas les donnees).
        entree->previous=NULL;
        entree->next=NULL;
        if(liste->t==0)
        {
            liste->first=entree;
            entree->previous=NULL;
        }
        else
        {
            ENTREE *courant;
            courant=liste->first;
            while(courant->next!=NULL)
            {
                courant=courant->next;
            }
            courant->next=entree;
            entree->previous=courant;
        }
        liste->t++;
    }
    La fonction tri_insertion qui fait maintenant appel à des sous-fonctions
    1- La premiere renvoie la plus petite entree de la liste (ordre alphabetique)
    2- La seconde délie l'entrée de la liste où elle se trouvait (en réajustant les ponteurs)
    3- Enfin , la troisièmme fonction ajoute l'entrée préalablement déliée à une nouvelle liste (la liste triée)
    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
     
    LISTE *tri_insertion(LISTE *liste,char choix)
    {
        LISTE *liste_triee;
        liste_triee=creer_liste();
        ENTREE *plus_petit;
        plus_petit=NULL;
        while(liste->t>0)
        {
            plus_petit=plus_petite_entree(liste,choix);
            delier_entree(plus_petit,liste);
            ajoute_entree(plus_petit,liste_triee);
        }
    free(liste);
    return liste_triee;
    }
     
    ENTREE *plus_petite_entree(LISTE *liste,char choix)
    {
        if(liste->t<2)
        {
            return(liste->first);
        }
        else
        {
            ENTREE *courant;
            ENTREE *plus_petit;
            courant=liste->first;
            plus_petit=liste->first;
            while(courant!=NULL)
            {
               if(choix=='n')
               {
                if(strcmp(courant->nom,plus_petit->nom)<0)
                {
                    plus_petit=courant;
                }
               }
     
               if(choix=='p')
               {
                if(strcmp(courant->prenom,plus_petit->prenom)<0)
                {
                    plus_petit=courant;
                }
               }
     
               if(choix=='c')
               {
                if(strcmp(courant->classe,plus_petit->classe)<0)
                {
                    plus_petit=courant;
                }
               }
                courant=courant->next;
            }
            return plus_petit;
        }
    }
     
    void delier_entree(ENTREE *entree,LISTE *liste)
    {
       if(liste->t<2)
       {
     
       }
       else if(entree->previous==NULL)
       {
          liste->first=entree->next;
          entree->next->previous=NULL;
       }
       else if(entree->next==NULL)
       {
          entree->previous->next=NULL;
       }
       else
       {
          entree->previous->next=entree->next;
          entree->next->previous=entree->previous;
       }
       liste->t--;
    }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 20/10/2012, 22h07
  2. liste chainée double
    Par Stevie Wonder dans le forum C
    Réponses: 11
    Dernier message: 21/11/2006, 12h13
  3. Algo de tri par liste chainée
    Par Treuze dans le forum C
    Réponses: 3
    Dernier message: 30/12/2005, 14h05
  4. Liste chainée double générique
    Par issou dans le forum C
    Réponses: 3
    Dernier message: 11/11/2005, 02h48
  5. tri de liste chainée
    Par RezzA dans le forum C
    Réponses: 7
    Dernier message: 26/01/2003, 20h25

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