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

Langage Delphi Discussion :

Pointeur - Liste chainées : une suppression de base !


Sujet :

Langage Delphi

  1. #1
    Leoxp
    Invité(e)
    Par défaut Pointeur - Liste chainées : une suppression de base !
    Salut à tous,

    Je viens d'opter pour mon application pour une liste chainée plutôt qu'un tableau. Tout marche bien sauf pour la suppression. Je suis sûr que c'est un problème bidon ! J'ai presque honte de poser la question ici

    En fait j'ai un type déclaré ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      pConseil = ^tpConseil;
      tpConseil = record
        val     : conseil;
        suivant : pConseil;
        end;
    Et ma procédure de suppression :

    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
    procedure tConseil.supprimer(noMatricule : integer);
    var
      pointeur,
      precedent : pConseil;
      trouve    : boolean;
    begin
      trouve:=false; pointeur:=tabConseil; precedent:=nil;
      while ((not trouve)and not(pointeur=nil)) do
      Begin
        if (pointeur^.val.id=noMatricule) Then
          trouve:=true
        else
        begin
          precedent:=pointeur;
          pointeur:=pointeur^.suivant;
        end;
      End;
      if (trouve) then
      begin
        If precedent=nil Then
          tabConseil:=pointeur.suivant
        Else
          precedent:=pointeur^.suivant;
        //dispose(pointeur);
        dec(nbConseils);
      end;
    end;
    Le problème est que si j'ai 4 éléments : toto, titi, tata, tutu
    En supprimant "titi", il m'affichera la liste : toto, tata, tutu, tutu.

    Et ensuite si je supprime "toto" : tata, tutu, tutu, tutu.


    Comme toujours j'ai épuisé toutes mes sources, sinon je ne viendrais pas vous ennuyer ici avec ça donc si quelqu'un pouvait m'aider à rectifier mon erreur, je lui en serait reconnaissant.

    Merci

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 50
    Points : 61
    Points
    61
    Par défaut
    salut,

    dans ta procedure de suppression, tu dois supprimer le dernier element chainer, et mettre un point nul sur l'avant dernier (fin de chainage).

    ainsi :

    1.Toto-2
    2.tata-3
    3.titi-4
    4.tutu-nil

    suppression de tata
    1.toto-2 // ne change pas
    2.tata-3 devient 2.titi-3 // on decale
    3.titi-4 devient 3.tutu-4
    4.tutu-nil devient supprimer
    et 4 - 1 (avant dernier) 3.titi-4 devient 3.titi-nil

    j'espere que cela est assez clair.

  3. #3
    Membre expert
    Avatar de e-ric
    Homme Profil pro
    Apprenti chat, bienfaiteur de tritons et autres bestioles
    Inscrit en
    Mars 2002
    Messages
    1 561
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Apprenti chat, bienfaiteur de tritons et autres bestioles

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 561
    Points : 3 951
    Points
    3 951
    Par défaut
    Salut

    Remarques :
    - Pourquoi se faire mal avec des pointeurs alors que l'on a des objets et des références dessus ! Avec une classe, c'est quand même plus classe ! Ah quand je veux faire de l'esprit, je suis très fort.

    - Raisonne en type abstrait de données de façon à mieux spécifier les opérations de ta classe.

    - Pourquoi as-tu mis dispose(pointeur) en commentaire, la suppression n'a ainsi jamais lieu. J'espère que tu as beaucoup de mémoire.

    - Même si le déréférencement de pointeur sur des record est automatique en Delphi (de la même manière qu'avec les références d'objet), choisis une fois pour toutes de rendre explicite ou implicite le déréférencement. Adopte dons une style cohérent, j'aurais tendance à le rendre explicite (permettra une meilleure détection des erreurs).

    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
     
    procedure tConseil.supprimer(noMatricule : integer);
    var
      pointeur,
      precedent : pConseil;
      trouve    : boolean;
    begin
      // Remarque :
      // il existe une recherche basée sur l'algorithme dit de la sentinelle
      // qui simplifie le test du while en ajoutant une cellule fictive
      // en fin de liste (valable pour les grandes listes)
      trouve:=false; pointeur:=tabConseil; precedent:=nil;
      while not (trouve or (pointeur=nil)) do
      Begin
        Trouve := (pointeur^.val.id = noMatricule);
        if not Trouve then
        begin
          precedent:=pointeur;
          pointeur:=pointeur^.suivant;
        end;
      End;
      if (trouve) then
      begin
        If precedent=nil Then
          // Cas du premier élément de la liste
          tabConseil:=pointeur^.suivant
        else
          // Ton erreur : il faut relier le suivant du précédent au suivant du courant
          // (subtil non !!)
          precedent^.suivant := pointeur^.suivant;
        dispose(pointeur);
        dec(nbConseils);
      end;
    end;
    Ca devrait marcher. Raisonne avec un bout de papier, dessine les liens avec des flèches et réalise les opérations pas à pas, ça aide.

    cdlt

    e-ric

    M E N S . A G I T A T . M O L E M
    Debian 64bit, Lazarus + FPC -> n'oubliez pas de consulter les FAQ Delphi et Pascal ainsi que les cours et tutoriels Delphi et Pascal

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

  4. #4
    Leoxp
    Invité(e)
    Par défaut
    Ton erreur : il faut relier le suivant du précédent au suivant du courant (subtil non !!)
    J'avais déjà essayé cette solution mais le problème qui se pose est toujours le même... J'ai des doublons qui se créé (le dernier élément de ma liste) dès que je supprime un autre élément...

    :

  5. #5
    Leoxp
    Invité(e)
    Par défaut LOL !!
    Autant pour moi

    Le problème ne venait pas de ma procédure de suppression mais de la procédure de sauvegarde de la liste dans un fichier. En fait je faisais un simple "reset" alors du coup même si ma liste n'avait que 3 éléments, le 4ème était toujours présent à la fin du fichier

    Un "rewrite" est tout marche bien à présent !

    merci à tous et bonne soirée :o

Discussions similaires

  1. Suppression d'un élément dans une liste chainée
    Par jbarreau-mainson dans le forum Débuter
    Réponses: 1
    Dernier message: 06/05/2009, 15h49
  2. Réponses: 5
    Dernier message: 15/03/2008, 21h44
  3. Réponses: 10
    Dernier message: 18/09/2007, 14h00
  4. suppression dans une liste chainée
    Par tomtom421 dans le forum C
    Réponses: 8
    Dernier message: 21/04/2007, 16h29
  5. Réponses: 8
    Dernier message: 01/04/2006, 10h10

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