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 :

Filtrer une liste chainée


Sujet :

C

  1. #1
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2012
    Messages : 20
    Points : 12
    Points
    12
    Par défaut Filtrer une liste chainée
    Bonsoir,
    je suis entrain de construire une fonction qui supprime des éléments d'une liste chaînée qui ont une occurrence <=x. D'après les cours et les tutos que je les ai trouvé sur internet j'ai constaté qu' il faut tester si l'élément a supprimer est au début de la liste ou non car la suppression au début de la liste n'est pas la même que dans dans une autre position de la liste.Je veut comprendre est ce que ce teste est obligatoire?
    j'ai tester ce bout de code mais il m'affiche toujours 0 et lorsque je le débugge il m'affiche
    une violation d’accès(erreur de segmentation) est apparue dans votre programme
    mais je vois pas pourquoi?pouvez vous m'aidez a trouver la faille dans mon 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
     
    T *filtrer(T *Liste,int Nb,float x)
    {
      T *head=NULL,*precedent=NULL,*next=NULL;
      T *courant=Liste;
      for(courant=Liste; courant!=NULL; courant=next) {
        next = courant->suiv;
        if (courant->occ<=x) 
         { courant=courant->suiv;
          free(courant);
          if (precedent!=NULL) 
          precedent->suiv = next;
        } else {
          precedent = courant;
          if (head==NULL) head=courant;
        }
      }
     
      return head;
    }
    cordialement

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    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 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Tu devrais essayer de soigner l'indentation pour que l'on puisse comprendre plus facilement ce que tu fais


    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
    T *head=NULL,*precedent=NULL,*next=NULL;
    T *courant=Liste;
    for(courant=Liste; courant!=NULL; courant=next)
    {
        next = courant->suiv;
        if (courant->occ<=x) 
        {
             courant=courant->suiv;//courant = next;
             free(courant);// ?? Ne devrait-il pas être placé une ligne avant ? Tu veux supprimer le (*courant) dont occ est <= x pas le (*courant) suivant le (*courant) dont occ est <= x non ?
             if (precedent!=NULL) 
                   precedent->suiv = next;
        }
        else
        {
          //Il ne manque pas un "precedent->suiv = courant;" ?
          precedent = courant;
          if (head==NULL) head=courant;
        }
    }

  3. #3
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    625
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 625
    Points : 1 564
    Points
    1 564
    Par défaut
    D'une manière générale, sans utiliser de nom de variables, voici de quoi supprimer une entrée <= X dans une liste doublement chaînée (first pointe sur le premier élement, last sur le dernier):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    courant=first;
    while(courant) {
    	if(courant->????<=X) {
    		if(courant->prev) courant->prev->next=courant->next;
    		else first=courant->next;
    		if(courant->next) courant->next->prev=courant->prev;
    		else last=courant->prev;
    		old=courant;
    		courant=courant->next;
    		free(old);
    		}
    	else courant=courant->next;
    	}
    Bien à toi. Edgar.
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  4. #4
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2012
    Messages : 20
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par edgarjacobs Voir le message
    D'une manière générale, sans utiliser de nom de variables, voici de quoi supprimer une entrée <= X dans une liste doublement chaînée (first pointe sur le premier élement, last sur le dernier):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    courant=first;
    while(courant) {
    	if(courant->????<=X) {
    		if(courant->prev) courant->prev->next=courant->next;
    		else first=courant->next;
    		if(courant->next) courant->next->prev=courant->prev;
    		else last=courant->prev;
    		old=courant;
    		courant=courant->next;
    		free(old);
    		}
    	else courant=courant->next;
    	}
    Bien à toi. Edgar.
    Merci bien Edgar pour votre réponse,mais j'ai une ambiguïté au niveau de la déclaration des pointeur tête et fin de la liste:est ce que cette déclaration ce fait d'une manière locale c'est a dire dans ma fonction filtrer ou dans dans la déclaration de ma liste chaînée?

  5. #5
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    625
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 625
    Points : 1 564
    Points
    1 564
    Par défaut
    Les pointeurs de début et de fin liste ont normalement été créés lors de la création de la liste. Sinon, comment savoir où commence la liste? Et comment ajouter un élément en fin de liste sans la parcourir au complet à chaque insertion (à moins que les nouveaux éléments soient toujours ajoutés au début, ou que l'insertion soit faite suivant un certain critère) ?
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  6. #6
    Membre habitué
    Profil pro
    amateur
    Inscrit en
    Avril 2012
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : amateur
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Avril 2012
    Messages : 145
    Points : 144
    Points
    144
    Par défaut
    Citation Envoyé par INSPIRATION Voir le message
    Bonsoir,
    [...] j'ai constaté qu' il faut tester si l'élément a supprimer est au début de la liste ou non car la suppression au début de la liste n'est pas la même que dans dans une autre position de la liste.Je veut comprendre est ce que ce teste est obligatoire?
    cordialement
    Je te conseille de te faire un petit dessin (en remplaçant les liens/pointeurs de début/fin de liste par le signe ensemble vide, par exemple). Représente ou note bien, "bêtement", les actions à effectuer pour supprimer un noeud, suivant les différents cas de position de celui-ci. Tu vas vite comprendre, je crois, c'est pas sorcier. Ce dépend aussi si la liste est simplement ou doublement chaînée, bien sûr.
    En cas de question, n'hésite pas à redemander,
    denis

  7. #7
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2012
    Messages : 20
    Points : 12
    Points
    12
    Par défaut
    Mille mercis pour vos conseils, d’après vos réponses j'ai conclu qu'il faut vérifier la position de l’élément a supprimer (début,milieu ou fin) en utilisant les pointeurs début et fin lors de la construction de ma liste chaîne(simplement chaînée),donc la déclaration de ces pointeurs est obligatoire.Désolé je vous dérange mais vu que je suis débutante en c,je trouve une difficulté dans l’utilisation et la manipulation des pointeurs surtout au niveau des liste chaînées.

  8. #8
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2012
    Messages : 20
    Points : 12
    Points
    12
    Par défaut
    D’après vos conseils je suis arrivé a écrire ce bout de code mais il me donne toujours comme résultat zéro (nombre de variable restante dans la liste après le filtrage=0),je vois pas pourquoi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    T *filtrer(T *Liste,int Nb,float x){
    T *courant;
    courant=Liste;
     while(courant!=NULL)//parcourir la liste
     { if(courant->fc<=Nb*x)//test sur le premier element{
     courant=courant->suiv;}
     else {
     courant->suiv=courant->suiv->suiv;
     
            }
     
    }
    }

  9. #9
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    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 012
    Points : 23 145
    Points
    23 145
    Par défaut
    edgarjacobs t'a donné un algorithme pour les liste doublement chaînée or tu essayes de l'utiliser pour des listes simplement chaînée.

    Voici un petit algorithme pour les listes simplement chaînées :

    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
     
    //traiter le cas de la liste vide
    //cas de la liste à 1 élément.
    Liste courant = debut;
    int k = 20;
     
    //traitement de tous les éléments sauf du premier
    tant que courant->suiv != NULL
         if(courant->suiv->x <= k)
         {
                   Liste tmp = courant->suiv->suiv;
                   //suppression du maillon
                   courant -> suiv = ... ;
          }
     
         courant = courant->suiv;
    fin tant que
     
    //traitement du premier élément
     
    return debut;

  10. #10
    Membre habitué
    Profil pro
    amateur
    Inscrit en
    Avril 2012
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : amateur
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Avril 2012
    Messages : 145
    Points : 144
    Points
    144
    Par défaut
    Citation Envoyé par INSPIRATION Voir le message
    D’après vos conseils je suis arrivé a écrire ce bout de code mais il me donne toujours comme résultat zéro (nombre de variable restante dans la liste après le filtrage=0),je vois pas pourquoi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    T *filtrer(T *Liste,int Nb,float x){
    T *courant;
    courant=Liste;
     while(courant!=NULL)//parcourir la liste
     { if(courant->fc<=Nb*x)//test sur le premier element{
     courant=courant->suiv;}
     else {
     courant->suiv=courant->suiv->suiv;
     
            }
     
    }
    }
    Il y a au moins 3 problèmes dans ton code :

    1. Il est presque illisible du fait de l'espacement et l'indentation. Voici un exemple (juste un exemple) de version plus lisible :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    T *filtrer(T *Liste, int Nb, float x) {
       // parcourir la liste en testant les elements suivant le critère
       // et supprimant les noeuds qui n'y répondent pas
       T *courant = Liste;
       while (courant != NULL) {
          // test sur l'element courant
          if (courant->fc <= Nb*x) {
             courant=courant->suiv;
          } else {
             courant->suiv = courant->suiv->suiv;
          }
       }
    }
    2. Tu n'as pas encore bien compris, apparemment, comment on peut supprimer un noeud dans une liste chaînée. Tu pourrais faire une mini-fonction 'supprimer_noeud' juste pour ça. Quel(s) paramètre(s) nécessite-t-elle ? Vérifie qu'elle marche bien ; puis utilise-la dans 'filtrer'. Ensuite, si tu n'en as pas besoin ailleurs, tu peux éventuellement en réintégrer le code dans filtrer.
    Indice: Tu as raison dans le fait que cela consiste à "sauter" un noeud comme tu le fais par "courant->suiv=courant->suiv->suiv". Mais (1) quel noeud est à sauter ? (2) quelles variables sont en jeu ?

    3. Tu ne traites pas spécialement le cas du premier noeud de la liste, malgré ta question initiale.
    Indice : Attention, comme dans la fonction 'filtrer' tu supprimes des noeuds, tu ne peux pas traiter le premier noeud avant de commencer le cycle (ce qui serait plus simple). Pourquoi ? Mais tu peux dans un premier traiter ce cas hors du cycle pour bien le comprendre, avec des données qui vont bien, puis le réintégrer dans le cycle.

    Denis

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Pour filtrer une liste simplement chaînée indépendamment du fait qu'un nœud soit le premier, il faut faire un parcours indirect: http://www.developpez.net/forums/d62...e/#post3675588
    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.

Discussions similaires

  1. Impossibilité de filtrer une liste déroulante
    Par lito74 dans le forum Access
    Réponses: 12
    Dernier message: 27/02/2006, 11h03
  2. Réponses: 4
    Dernier message: 25/12/2005, 18h46
  3. Réponses: 2
    Dernier message: 10/10/2005, 02h25
  4. [Stratégie]Sauvegarde d'une liste chainée dans un fichier
    Par BernardT dans le forum Général Java
    Réponses: 17
    Dernier message: 25/07/2005, 17h04
  5. manipulation d'une liste chainé
    Par sorari dans le forum C++
    Réponses: 1
    Dernier message: 16/03/2005, 12h32

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