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 :

Les listes triées


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Étudiant
    Inscrit en
    Août 2007
    Messages
    419
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2007
    Messages : 419
    Par défaut Les listes triées
    Bonjour,

    Je trouve un petit problème avec les pointeurs et les listes en C

    je réalise un petit programme tout simple qui insère un nouvel élément dans une liste triée.

    dans mon exemple, une liste d'éléments triées par ordre croissant des numéros de références:

    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
     
    #include <stdio.h>
    #include <alloc.h>
    #include <conio.h>
     
    typedef struct liste
    {
    char nom;
    int num_ref;
    liste *suiv;
    }
    liste * debut, *courant, *nouveau;
    char reponse;
    void insert (char nom, int num_ref) {
     
    /*création de la liste*/
     
    debut=liste*malloc(sizeof(liste));
    courant=debut;
    do {
    clrscr();
    printf(" /n entrez le nom");
    scanf("%s", courant->nom);
    printf("/n entrez le numéro de référence");
    scanf("%d", courant->num_ref);
     
    printf("avez vous un autre élément à saisir? o/n");
    reponse=getche();
    if (reponse='o' ou 'O')
    {
    nouveau=liste*malloc(sizeof(liste));
    printf("/n entrez le nom");
    printf("/n entrez le numéro de référence");
    scanf("%s%d", nouveau->nom, nouveau->num_ref);
    ref=nouveau->num_ref;
     
    /*parcours de la liste*/
     
    courant=debut
    if (courant->num_ref > ref) /*tester la tête de la liste avec le numéro de référence du nouveau élément*/
    /*insertion en tête de liste*/
    {
    nouveau->suivant=debut;
    debut=nouveau;
    }
    else 
     while (courant->suivant!=NULL)
     {
     courant=courant->suivant;
     if (courant->num_ref < ref)
     /*insérer au milieu*/
     {
     nouveau->suivant=courant->suivant;
     courant->suivant=nouveau;
     }
    }
    else
     if (courant->suivant=NULL)
     {
     nouveau->suivant=NULL;
     courant->suivant=nouveau;
    }
     
    }
    qu'en pensez vous?

    Merci

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    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 835
    Billets dans le blog
    1
    Par défaut
    Ce que j'en pense ? Ben je pense que je ne comprends pas pourquoi ta procédure d'insertion est placée dans un while() ou alors j'ai pas compris ce que tu cheches à faire. On insère bien un seul élément non ? Si c'est le cas alors mettre l'algo d'insertion dans une boucle n'est pas une bonne idée.

    Autre détail: tu devrais découper ton problème en taches élémentaires et faire faire ces tâches par des fonctions. Cela allègera ton code et tu pourras ensuite utiliser et réutiliser tes fonctions quand ton programme évoluera (par exemple si demain tu décides que les éléments à insérer seront pris dans un fichier tu pourras facilement rajouter cette branche à ton programme)
    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]

  3. #3
    Membre éclairé
    Étudiant
    Inscrit en
    Août 2007
    Messages
    419
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2007
    Messages : 419
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Ce que j'en pense ? Ben je pense que je ne comprends pas pourquoi ta procédure d'insertion est placée dans un while() ou alors j'ai pas compris ce que tu cheches à faire. On insère bien un seul élément non ? Si c'est le cas alors mettre l'algo d'insertion dans une boucle n'est pas une bonne idée.

    Autre détail: tu devrais découper ton problème en taches élémentaires et faire faire ces tâches par des fonctions. Cela allègera ton code et tu pourras ensuite utiliser et réutiliser tes fonctions quand ton programme évoluera (par exemple si demain tu décides que les éléments à insérer seront pris dans un fichier tu pourras facilement rajouter cette branche à ton programme)
    Bonsoir,

    je cherche à insérer un nouvel élément dans la liste triée, cette insertion pourrait se faire en début, au milieu ou en fin de liste.

    je le fait en boucle pour insérer tout en gardant une liste triée, donc à chaque fois que l'utilisateur veut introduire un nouveau produit, il indique son nom et son num de ref et les le tout est trié selon les num de référence

  4. #4
    Membre éclairé Avatar de archer
    Ingénieur développement logiciels
    Inscrit en
    Mai 2007
    Messages
    338
    Détails du profil
    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 338
    Par défaut
    Salut
    Ce que j’ai compris dans la fonction en question : c’est que tu donnes les paramètres du nouveau élément en argument au même temps tu vas créer la liste tout en la triant pour qu’enfin tu puisse insérer le nouveau élément.

    Si c’est le cas, alors je te suggère de créer le premier élément tout seul, puis utiliser la fonction insert avec quelques rectifications de tel manière à insérer le nouveau élément dans sa place sans boucler puis dans le main faire le test si l’utilisateur veut ajouter un nouveau élément tout en utilisant cette boucle.
    J’espère que ça va te servir.

  5. #5
    Membre éclairé
    Étudiant
    Inscrit en
    Août 2007
    Messages
    419
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2007
    Messages : 419
    Par défaut
    Bonsoir,

    alors suivant vos conseils, j'ai refait mon programme différemment en le décomposant en fonctions.

    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
    #include <stdio.h>
    #include <conio.h>
    #include <alloc.h>
     
    typedef struct liste
    {
    char nom;
    int num_ref;
    *suivant;
    }
     
    liste * debut, *courant, *nouveau;
    char reponse;
     
    void creer_premier()
    void insert(char nom, int num_ref);
    void insert_debut();
    void insert_milieu();
    void insert_fin();
    void main()
    {
    printf("/n entrez le nom du produit");
    printf("/n entrez la référence");
    creer_premier();
    printf("voulez-vous une autre saisie?");
    reponse=getche();
    while (reponse=='o' || reponse=='O')
    nouveau=liste*malloc(sizeof(liste));
    insert(nom,num_ref);
     
    }
     
    void creer_premier(nom, num_ref)
    {
    debut=liste*malloc(sizeof(liste));
    courant=debut;
    ]
     
    void insert(nom, num_ref) 
    {
    courant=debut;
    if (courant->suivant > num_ref)
    {
    insert_debut();
    }
    else
    {
    while (courant->suivant != NULL)
    {
    courant=courant->suivant;
    if (courant->num_ref < ref)
    insert_milieu();
    }
    }
    else
    insert_fin();
     
    }
     
    void insert_debut()
    {
    nouveau->suivant=debut;
    debut=nouveau;
    }
     
    void insert_milieu()
    {
    nouveau->suivant=courant->suivant;
    courant->suivant=nouveau;
    }
     
    void insert_fin()
    {
    nouveau->suivant=NULL;
    courant->suivant=nouveau;
    }
     
    }
    s'il vous plait..

  6. #6
    Membre Expert
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Par défaut
    déjà corrige les erreurs de syntaxe comme les points virgule, etc.
    puis tu n'as pas déclaré dans le main les variables nom et num_ref.

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    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 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par acacia Voir le message
    Bonsoir,

    je cherche à insérer un nouvel élément dans la liste triée, cette insertion pourrait se faire en début, au milieu ou en fin de liste.

    je le fait en boucle pour insérer tout en gardant une liste triée
    Je sais comment on se sert d'une liste triée et comment on insère. Ce que je veux te dire c'est que t'as pas besoin de mettre l'insertion dans le while.
    Il te faut
    1) chercher la position où ira s'insérer le nouvel élément (là il faut un while)
    2) une fois qu'on a trouvé la position (donc après le while) il te faut insérer l'élément en cours

    Citation Envoyé par acacia Voir le message
    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
    #include <stdio.h>
    #include <conio.h>
    #include <alloc.h>
     
    typedef struct liste
    {
    char nom;
    int num_ref;
    *suivant;
    }
     
    liste * debut, *courant, *nouveau;
    char reponse;
     
    void creer_premier()
    void insert(char nom, int num_ref);
    void insert_debut();
    void insert_milieu();
    void insert_fin();
    void main()
    {
    printf("/n entrez le nom du produit");
    printf("/n entrez la référence");
    creer_premier();
    printf("voulez-vous une autre saisie?");
    reponse=getche();
    while (reponse=='o' || reponse=='O')
    nouveau=liste*malloc(sizeof(liste));
    insert(nom,num_ref);
     
    }
     
    void creer_premier(nom, num_ref)
    {
    debut=liste*malloc(sizeof(liste));
    courant=debut;
    ]
     
    void insert(nom, num_ref) 
    {
    courant=debut;
    if (courant->suivant > num_ref)
    {
    insert_debut();
    }
    else
    {
    while (courant->suivant != NULL)
    {
    courant=courant->suivant;
    if (courant->num_ref < ref)
    insert_milieu();
    }
    }
    else
    insert_fin();
     
    }
     
    void insert_debut()
    {
    nouveau->suivant=debut;
    debut=nouveau;
    }
     
    void insert_milieu()
    {
    nouveau->suivant=courant->suivant;
    courant->suivant=nouveau;
    }
     
    void insert_fin()
    {
    nouveau->suivant=NULL;
    courant->suivant=nouveau;
    }
     
    }
    Bon ben des erreurs courantes
    1) main est de type "int" et non "void"
    2) les variables globales sont inutiles et sources de bug potentiel. Essaye de prendre l'habitude de déclarer dans tes fonctions les variables nécessaires au travail de la fonction et que les fonctions ayant besoin des valeurs d'autres fonctions les reçoivent en paramètre...
    3) tu crées un typedef sur une structure mais tu dis pas comment se nommera le type que tu crées => corollaire => le type "liste" n'existe pas
    4) euh... pourquoi cette accolade supplémentaire après la dernière fonction ???

    Autre détail => tu as créé une fonction qui te crée le premier élément puis ensuite, quand il faut en rajouter, tu les alloues dans le main. Tu aurais écrit une fonction qui crée un élément quel qu'il soit, tu aurais pu l'appeler pour le premier et aussi pour tous les autres...
    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]

  8. #8
    Membre éclairé
    Étudiant
    Inscrit en
    Août 2007
    Messages
    419
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2007
    Messages : 419
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Je sais comment on se sert d'une liste triée et comment on insère. Ce que je veux te dire c'est que t'as pas besoin de mettre l'insertion dans le while.
    Il te faut
    1) chercher la position où ira s'insérer le nouvel élément (là il faut un while)
    2) une fois qu'on a trouvé la position (donc après le while) il te faut insérer l'élément en cours



    Bon ben des erreurs courantes
    1) main est de type "int" et non "void"
    2) les variables globales sont inutiles et sources de bug potentiel. Essaye de prendre l'habitude de déclarer dans tes fonctions les variables nécessaires au travail de la fonction et que les fonctions ayant besoin des valeurs d'autres fonctions les reçoivent en paramètre...
    3) tu crées un typedef sur une structure mais tu dis pas comment se nommera le type que tu crées => corollaire => le type "liste" n'existe pas
    4) euh... pourquoi cette accolade supplémentaire après la dernière fonction ???

    Autre détail => tu as créé une fonction qui te crée le premier élément puis ensuite, quand il faut en rajouter, tu les alloues dans le main. Tu aurais écrit une fonction qui crée un élément quel qu'il soit, tu aurais pu l'appeler pour le premier et aussi pour tous les autres...
    Bonjour Sve@r merci pour la réponse, je vais corriger tout de suite ces erreurs.

    j'ai une petite question, y a t-il plusieurs manière de déclarer les listes chainées?

  9. #9
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    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 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par acacia Voir le message
    j'ai une petite question, y a t-il plusieurs manière de déclarer les listes chainées?
    Personnellement je préconise de déclarer 2 structures
    1) la structure permettant de manipuler un élément qui contient donc les infos de l'élément et le pointeur sur le suivant et éventuellement d'autres pointeurs sur d'autres suivants (si par exemple on veut faire une liste triée sur plusieurs critères)
    2) une structure qui permet de manipuler la liste. Ca peut paraître trivial vu qu'il suffit d'avoir le premier élément et que déclarer une structure juste pour ça c'est idiot mais une fois qu'on a la structure, on peut ensuite évoluer plus facilement. Par exemple si on a envie d'avoir aussi le nombre d'éléments on peut mettre cette info dans cette structure. Si on fait une liste triée sur plusieurs critères alors il y aura plusieurs "premiers" éléments et donc on peut rajouter tous ces pointeurs plus facilement dans une structure déjà toute faite que si on décide de la créer après coup parce qu'on voit qu'on se met à en avoir besoin

    Par exemple voici une bonne base pour démarrer
    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
    // Les structures
    typedef struct s_elem {
        <...>
        struct s_elem *next;
    } t_elem;
     
    typedef struct s_liste {
        t_elem *debut;
        unsigned long nb
    } t_liste;
     
    // Fonction qui nettoie une liste de tous ses éléments résiduels
    void freeListe(t_liste *liste)
    {
        t_elem *cur;
     
        // Traitement de toute la liste
        while (liste->debut != NULL)
        {
            cur=liste->debut;
            liste->debut=liste->debut->next;
            free(cur);
        }
     
        liste->nb=0;
    }
     
    // Fonction qui initialise une liste
    void initListe(t_liste *liste)
    {
        liste->debut=NULL;
        liste->nb=0;
    }
     
    // Fonction qui crée un élément et le remplit
    t_elem *ajoutElem(<... infos à remplir ...>)
    {
        t_elem *elem;
     
        // Création de l'élément - Vérification création
        elem=malloc(sizeof t_elem);
        if (elem == NULL)
           return NULL;
     
        // Remplissage de l'élément
        elem->...=...;
        elem->...=...;
        elem->next=NULL;
     
        // Renvoi de l'élément créé
        return elem;
    }
     
    // Fonction qui insère un élément après un autre ou au début 
    void insereElem(t_liste liste, t_elem *pos, t_elem *elem)
    {
        // S'il faut insérer au début (pos conventionnelement égal à NULL)
        if (pos == NULL)
        {
             // L'élément récupère le début
             elem->next=liste->debut;
     
             // Le début change
             liste->debut=elem;
        }
        else
        {
             // L'élément récupère le suivant de celui après lequel il s'ajoute
             elem->next=pos->next;
     
             // L'élément s'insère
             pos->next=elem;
        }
     
        // On a un élément en plus
        liste->nb++;
    }
    Voilà une ébauche de ce que je ferais si je devais manipuler des listes...
    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]

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

Discussions similaires

  1. Optimiser les performances try/catch ?
    Par KiLVaiDeN dans le forum Langage
    Réponses: 4
    Dernier message: 14/01/2014, 13h47
  2. Tri sur les listes
    Par frizou11 dans le forum Général Python
    Réponses: 4
    Dernier message: 14/05/2006, 11h33
  3. [Liste]Tri
    Par GreenJay dans le forum Collection et Stream
    Réponses: 6
    Dernier message: 02/09/2004, 13h39
  4. [langage] probleme avec les listes dans des listes
    Par pqmoltonel dans le forum Langage
    Réponses: 7
    Dernier message: 27/04/2004, 12h32
  5. [LG]Les listes
    Par franck H dans le forum Langage
    Réponses: 2
    Dernier message: 16/01/2004, 15h15

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