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 :

Suppression élément dans liste


Sujet :

C

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 88
    Points : 53
    Points
    53
    Par défaut Suppression élément dans liste
    Salut à tous,

    Voilà je voudrais supprimer un élément dans une liste chainée.

    J'ai la structure suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    typedef struct objet {
    	char * s; /* nom de l'objet */
    	int x; /* numéro de l'objet pointé */
    	struct objet * suiv; /* objet suivant */
    	} Objet;
     
    typedef Objet * listeObjet;
    J'ai une liste de type listeObjet à laquelle je voudrais supprimer un élément . Par exemple je veux supprimer l'objet ayant pour numéro 5.

    Voilà merci de m'aider, car là je galère depuis 2 jours :s[/code]

  2. #2
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Voilà merci de m'aider, car là je galère depuis 2 jours
    Donne ton code qui ne marche pas et on verra pourquoi ça plante...

    Jc

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 88
    Points : 53
    Points
    53
    Par défaut
    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
     
    void supprimer_dans_liste(listeObjet * lO, int x)
    /* specif : supprime l'objet x dans la liste lO                             */
    {
       listeObjet tmp = *lO;
     
       if((*lO)->som == x)
       {
          (*lO) = (*lO)->suiv;
          free(tmp);
          return;
       }
     
       while(tmp != NULL)
       {
          if(tmp->som == x)
          {
             free(tmp);
             tmp = tmp->suiv;
             return;
          }
          tmp = tmp->suiv;
       }
       return;
    }
     
    void total_destroy_liste(listeObjet * lO)
    /* specif : suppression totale d'une liste                                    */
    {
       while((*lO) != NULL)
       {
          free(*lO);
          *lO = (*lO)->suiv;
       }
    }
    Voilà le total_destroy_liste marche ( je pense ), par contre le supprimer_dans_liste ne marche pas :/

  4. #4
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par bugmenot
    Voilà le total_destroy_liste marche ( je pense ), par contre le supprimer_dans_liste ne marche pas :/
    Ce sujet a été abordé récemment.

    http://www.developpez.net/forums/vie...397113#2397113

  5. #5
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut

    Ce sujet a été abordé récemment.

    http://www.developpez.net/forums/vie...397113#2397113
    Pour ne pas relancer la discussion, je ne vais pas reprendre ton code mais juste quelques remarques sur ton code:

    • Il ne faut pas faire un free si on utilise après l'élément:
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
       
            free(tmp);
            tmp = tmp->suiv;
            return; 
            ...
            free(*lO);
            *lO = (*lO)->suiv;
      Lorsqu'on veut modifier une liste chaînée (et plus particulièrement le chaînage), il faut soit retourner la liste modifiée, soit passer une double indirection pour modifier (dans le cas nécessaire) le premier élément.
      Lorsque je code une liste chaînée j'ai une préférence avec la première solution (je crois que c'est une question d'habitude), mais elle est trompeuse. On a une tendance à croire que la fonction rend une nouvelle liste chaînée différente, ce qui est faux...

      Je te conseille donc la deuxième puisqu'elle est plus claire: on risque de modifier la liste!


    Pour tout le reste, regarde le lien d'Emmanuel
    Jc

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 88
    Points : 53
    Points
    53
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    typedef struct objet {
       char * s; /* nom de l'objet */
       int x; /* numéro de l'objet pointé */
       struct objet * suiv; /* objet suivant */
       } Objet;
     
    typedef Objet * listeObjet;
    J'ai réussi un total_destroy_liste qui marche

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    void total_destroy_liste(listeObjet * lO)
    /* specif : suppression totale d'une liste                                    */
    {
       listeObjet tmp;
     
       while(*lO != NULL)
       {
          tmp = (*lO)->suiv;
          free(*lO);
          *lO = tmp;
       }
    }
    Par contre pour supprimer un élément, y'a rien à faire :/[/code]

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 88
    Points : 53
    Points
    53
    Par défaut
    Meme avec le post précédent et le lien d'emmanuel, je n'y arrive pas

  8. #8
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    L'algorithme serait:

    Si c'est le premier élément
    Efface le premier élément
    Retourne le reste de la liste
    Sinon
    Chercher l'élément qu'il faut supprimer
    Le retirer
    Retourner la liste modifiée

    Ex:
    Liste de départ: A -> B -> C -> D
    Suppression de A: On remarque que c'est le premier élément donc on sauvegarde l'adresse de B, on fait un free sur A et on retourne B...

    Suppression de C:
    On parcourt la liste chaînée jusqu'à B,
    on remarque que le prochain est C donc on stocke l'adresse de C dans une variable temporaire, on change le chaînage de B pour qu'il pointe vers D et on fait un free sur C,
    on retourne l'adresse A qui est le début de la liste...

    Essaie avec toutes ces infos...

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 88
    Points : 53
    Points
    53
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    typedef struct objet {
       char * s; /* nom de l'objet */
       int x; /* numéro de l'objet pointé */
       struct objet * suiv; /* objet suivant */
       } Objet;
     
    typedef Objet * listeObjet;
    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
    listeObjet supprimer_dans_liste(listeObjet lO, int x)
    /* specif : supprime le sommet x dans la liste lO                             */
    {
       listeObjet tmp = lO, tmp2, deb = lO;
     
       if(lO->som == x)
       {
          tmp = lO->suiv;
          free(lO);
          return tmp;
       }
     
       while(tmp->suiv != NULL && tmp->suiv->som != x)
       {
          tmp = tmp->suiv;
       }
       if(tmp->suiv->som == x)
       {
          tmp2 = tmp->suiv;
          tmp = tmp->suiv->suiv;
          free(tmp2);
       }
       return deb;
    }
    Qui ne marche toujours pas

  10. #10
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Lorsqu'on travaille avec des pointeurs il ne faut pas oublier les tests de base...

    Voici ton code commente:

    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
     
    listeObjet supprimer_dans_liste(listeObjet lO, int x)
    /* specif : supprime le sommet x dans la liste lO                             */
    {
       //fy: pas besoin de deb, tu as toujours l0...
       listeObjet tmp = lO, tmp2, deb = lO;
     
        //fearyourself: il faut commencer par tester si l0 == NULL
        //si c'est le cas, on retourne NULL...
     
       //fy: Cette partie est juste sauf que tu ne desalloue pas s (nom de l'objet)
       //fy: Comment est-ce que tu alloue ces chaines de caracteres?
       //fy: Pourquoi som? t'avais x dans ta structure, t'as change ta structure?
       if(lO->som == x)
       {
          tmp = lO->suiv;
          free(lO);
          return tmp;
       }
     
       //fy: Je suis d'accord sur cette boucle
       while(tmp->suiv != NULL && tmp->suiv->som != x)
       {
          tmp = tmp->suiv;
       }
     
       //fy: Il faut tester tmp->suiv!=NULL D'ABORD!!!
       if(tmp->suiv->som == x)
       {
          tmp2 = tmp->suiv;
     
          //fy: mauvaise affectation des liens, c'est tmp->suiv que tu veux changer...
          tmp = tmp->suiv->suiv;
     
          //fy: meme remarque pour tmp2->s...
          free(tmp2);
       }
     
       //retourne juste l0....
       return deb;
    }

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 88
    Points : 53
    Points
    53
    Par défaut
    Oui j'ai changé la structure, j'ai un char au lieu d'un char * :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    typedef struct objet {
       char c; /* nom de l'objet */
       int x; /* numéro de l'objet pointé */
       struct objet * suiv; /* objet suivant */
       } Objet;
     
    typedef Objet * listeObjet;
    Par contre MERCI pour ton aide, j'ai enfin compris, et CA MARCHE, voilà :

    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
    listeObjet supprimer_dans_liste(listeObjet lO, int x)
    /* specif : supprime le sommet x dans la liste lO                             */
    {
       listeObjet tmp = lO, tmp2;
     
       if(lO == NULL) return NULL;   
     
       if(lO->x == x)
       {
          tmp = lO->suiv;
          free(lO);
          return tmp;
       }
     
       while(tmp->suiv != NULL && tmp->suiv->x != x)
       {
          tmp = tmp->suiv;
       }
       if(tmp->suiv != NULL && tmp->suiv->x == x)
       {
          tmp2 = tmp->suiv;
          tmp->suiv = tmp->suiv->suiv;
          free(tmp2);
       }
       return lO;
    }
    ENCORE UN GRAND MERCI fearyourself !

    Pour mon total_destroy_liste, ca peut aller tu crois ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void total_destroy_liste(listeObjet * lO)
    /* specif : suppression totale d'une liste                                    */
    {
       listeObjet tmp;
     
       while(*lO != NULL)
       {
          tmp = (*lO)->suiv;
          free(*lO);
          *lO = tmp;
       }
    }

  12. #12
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    CA MARCHE
    Je suis d'accord mais tu peux simplifier ce test:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if(tmp->suiv != NULL && tmp->suiv->x == x)
    en

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if(tmp->suiv != NULL)
    parce que: si tu sors de ta boucle, soit tmp->suiv==NULL et donc on est a la fin de la liste, soit tmp->suiv->x == x...

    Si tmp->suiv!=NULL alors forcement tmp->suiv->x==x!

    Sinon rajoute quelques commentaires pour que tu te souviennes de tout ca la prochaine fois et ca me semble bien...

    Pour mon total_destroy_liste, ca peut aller tu crois ?
    Oui c'est bien

    ENCORE UN GRAND MERCI fearyourself !
    De rien mais de toute facon c'est toi qui a fait le boulot, felicitations! ;-)

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 88
    Points : 53
    Points
    53
    Par défaut
    Et en plus t'es modeste

    Allé bonne soirée, merci encore :p

Discussions similaires

  1. [MySQL] Ajouter élément dans liste de sélection
    Par nadia lydia dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 12/06/2009, 20h42
  2. Suppression élément de liste lié
    Par Kyoku_FK dans le forum SharePoint
    Réponses: 9
    Dernier message: 02/06/2009, 15h02
  3. Réponses: 2
    Dernier message: 03/05/2009, 20h20
  4. syntaxe de recherche d'un élément dans liste
    Par mussara dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 26/10/2006, 19h17
  5. Ajout nouveaux éléments dans liste de choix
    Par Crazyblinkgirl dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 23/06/2006, 15h17

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