Forum |  HardWare.fr | News | Articles | PC | Prix | S'identifier | S'inscrire | Aide | Shop Recherche
489 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  C++ liste chainée

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

C++ liste chainée

n°2171562
darhkan
Posté le 16-01-2013 à 19:59:09  profilanswer
 

Bonsoir,
 
j'ai un soucis au niveau d'une fonction qui compte le nombre d'element dans ma liste chainée.
Ma fonction est la suivante:
int CountListNode( ListNode* node )
{
      int result = 0;
      while(node->m_next!=NULL)
      {
           result++;
           node=node->m_next;
      }
      return result;
}
 
Quand j'execute mon code, je n'ai pas d'erreur a la compilation mais quand ma console s'ouvre elle plante.
Savez vous d'ou vient le probleme?
 
Merci d'avance.

mood
Publicité
Posté le 16-01-2013 à 19:59:09  profilanswer
 

n°2171568
x1fr
Posté le 16-01-2013 à 20:12:38  profilanswer
 

Il me semble qu'il faut utiliser une variable temporaire
 

Code :
  1. int CountListNode( ListNode* node )
  2. {
  3.       ListeNode* tmpNode = node;
  4.       int result = 0;
  5.       while(tmpNode->m_next!=NULL)
  6.       {
  7.            result++;
  8.            tmpNode=tmpNode->m_next;
  9.       }
  10.       return result;
  11. }


---------------
Origin / PSN / Steam / Uplay : x1fr - bnet : Fab#2717
n°2171580
TwX
Posté le 16-01-2013 à 22:15:00  profilanswer
 

Bonsoir,
 
C'est quoi le test que tu fais aussi ?
Si node vaut null alors node->m_next existe pas et plante
 
 

Code :
  1. int CountListNode( ListNode* node )
  2. {
  3.     ListeNode* tmpNode = node;
  4.     int  result = 1;
  5.     if (node == NULL)
  6.           return 0;
  7.     while(tmp->m_next!=NULL)
  8.      {
  9.            result++;
  10.            tmp=tmp->m_next;
  11.       }
  12.       return result;
  13. }

n°2171581
darhkan
Posté le 16-01-2013 à 22:20:56  profilanswer
 

Voila mon programme final:
 
#include <stdio.h>
#include <tchar.h>
#include <assert.h>
#include <process.h>
#include <cstdlib>
#include <iostream>
 
 
using namespace std;
class ListNode
{
public:
ListNode(int value){}
int m_value;
ListNode* m_next;
};
 
int CountListNode( ListNode* node )
{
    int result = 0;
 
    while(node->m_next!=NULL)
    {
        result++;
        node=node->m_next;
    }
 
    return result+1;
}
 
ListNode* ReverseList( ListNode* node )
{
    ListNode *tmp = NULL;
    ListNode *result=NULL;
 
    while(node!=NULL)
    {
        tmp=node;
        node=tmp->m_next;
        tmp->m_next=result;
        result=tmp;
    }
    return result;
}
 
void afficherListe(ListNode* node)
{
    ListNode*tmp = node;
    while(tmp != NULL)
    {
        printf("val = %d et adresse du suivant = %d\n",tmp->m_value, tmp->m_next);
    tmp = tmp->m_next;
    }
    printf("\n" );
}
 
int main()
{
    printf("List Test:\n" );
 
    ListNode node1(1);
    ListNode node2(2);
    ListNode node3(3);
 
    node1.m_next = &node2;
    node2.m_next = &node3;
    node3.m_next = NULL;
 
   afficherListe(&node1);
   ListNode *reverted = ReverseList(&node1);
 
return 0;
}
 
J'ai réglé mon soucis de console qui plante.
Mais il me semble qu'il m'affiche les adresse avec afficherliste pourtant j'avais déja bosser sur un tp du genre et j'avais pas de soucis ca me retournais bien des entiers dans m_value.

n°2171582
darhkan
Posté le 16-01-2013 à 22:29:33  profilanswer
 

Ha c'est bon j'ai rien dit. J'ai réussi a me corriger tout seul j'avais oublier le constructeur.....
Merci tout de meme.

n°2171583
gilou
Modérateur
Modzilla
Posté le 16-01-2013 à 22:57:09  profilanswer
 

Ce serait un poil plus simple et plus clair ainsi IMHO:

Code :
  1. int CountListNode( ListNode* node )
  2. {
  3.     int result = 0;
  4.     while (node) {
  5.         ++result;
  6.         node = node->m_next;
  7.     }
  8.     return result;
  9. }


 
ou bien en un peu plus compact
 

Code :
  1. int CountListNode( ListNode* node )
  2. {
  3.     int result = 0;
  4.     if (node) do { ++result; } while ((node = node->m_next));
  5.     return result;
  6. }


 
A+,


Message édité par gilou le 16-01-2013 à 23:00:49

---------------
Samantha Fish Rulez!     --    Iyashikei Anime Forever!    --    In umbra igitur pugnabimus. --
n°2171588
Trap D
Posté le 17-01-2013 à 00:51:18  profilanswer
 

Le deuxième code est plus que superflu !

n°2171637
gilou
Modérateur
Modzilla
Posté le 17-01-2013 à 12:13:16  profilanswer
 

Pour ceux qui ne codent pas souvent en C sans doute, car pour un programmeur C, ça se lit direct:
Faire une incrémentation du compteur tant qu'il y a un noeud suivant.
 
A+,  


---------------
Samantha Fish Rulez!     --    Iyashikei Anime Forever!    --    In umbra igitur pugnabimus. --
n°2172528
cantor
Posté le 24-01-2013 à 18:51:57  profilanswer
 

Et la version récursive, plus belle, plus subtile :

 
Code :
  1. int CountListNode (ListNode *node) {
  2.     if (node) return 1 + CountListNode (node->m_next);
  3.     else return 0;
  4. }
 

On peut faire pareil avec les autres fonctions (ex pour afficherListe)

 
Code :
  1. void afficherListe (ListNode *node) {
  2.    if (node) cout << "Valeur: " << node->m_value << endl;
  3.    afficherListe (node->m_text);
  4. }
 

Ca permet aussi très facilement d'afficher la liste à l'envers:

 
Code :
  1. void afficherListeALenvers (ListNode *node) {
  2.    if (node == NULL) return;
  3.    afficherListeALenvers (node->m_text);
  4.    cout << "Valeur: " << node->m_value << endl;
  5. }


   


Message édité par cantor le 24-01-2013 à 19:03:28

---------------
Si ma chaussure est étroite, que m´importe que le monde soit vaste.
n°2172532
gilou
Modérateur
Modzilla
Posté le 24-01-2013 à 19:16:53  profilanswer
 

Citation :

Et la version récursive, plus belle, plus subtile :


Ainsi, elle n'a pas grand intérêt, puisque pas optimisable par le compilateur, contrairement à celle ci qui fait de la tail-récursion:
 
int CountListNodeRec (ListNode *node, int acc) {
    if (!node) return acc;
    return CountListNode (node->m_next, ++acc);
}
 
int CountListNodeRec (ListNode *node) {
    return CountListNodeRec (node, 0);
}
 
A+,


---------------
Samantha Fish Rulez!     --    Iyashikei Anime Forever!    --    In umbra igitur pugnabimus. --
mood
Publicité
Posté le 24-01-2013 à 19:16:53  profilanswer
 

n°2172535
Trap D
Posté le 24-01-2013 à 20:05:01  profilanswer
 

gilou a écrit :

Pour ceux qui ne codent pas souvent en C sans doute, car pour un programmeur C, ça se lit direct:
Faire une incrémentation du compteur tant qu'il y a un noeud suivant.
 
A+,  

Qu'on m'explique l'avantage de if (node) do par rapport au while (node)  en terme de beauté/élégance de code.  
Cela revient à faire un test inutile de plus il me semble.

n°2172546
gilou
Modérateur
Modzilla
Posté le 24-01-2013 à 21:53:10  profilanswer
 

Trap D a écrit :

Qu'on m'explique l'avantage de if (node) do par rapport au while (node)  en terme de beauté/élégance de code.  
Cela revient à faire un test inutile de plus il me semble.

Eh bien comptes le nombre de tests, et tu verras qu'il y en a exactement le même nombre dans chaque cas.
Et l'intérêt du do { ++result; } while ((node = node->m_next)); c'est de mettre en relief dans le test du while la partie qui évolue au fur et a mesure du parcours, plutôt que de la coller quelque part dans le bloc du while. Bref cela permet ici de séparer ce qu'on veut faire a chaque étape, dans le corps du bloc, du procédé de passage d'une étape à la suivante, dans le test d'arrêt du while. On sépare la partie 'itération' de la partie 'traitement à chaque itération'. Ici le traitement est trivial, certes, mais c'est une bonne idée IMHO de se placer dans un contexte un peu homologue à celui des itérateurs.
 
A+,


Message édité par gilou le 24-01-2013 à 22:01:54

---------------
Samantha Fish Rulez!     --    Iyashikei Anime Forever!    --    In umbra igitur pugnabimus. --
n°2172553
cantor
Posté le 24-01-2013 à 22:14:41  profilanswer
 

gilou a écrit :

Citation :

Et la version récursive, plus belle, plus subtile :


Ainsi, elle n'a pas grand intérêt, puisque pas optimisable par le compilateur...


 
Bah elle a l'intérêt de fonctionner et de pas changer ses interfaces ni de rajouter une seconde fonction. (Quoi que en C++ on doit pouvoir donner une valeur par défaut au second argument et l'appeler avec qu'un seul argument).
Mais c'est vrai, et au passage, par défaut, GCC n'effectue pas d'optimisation des fonctions récursives terminales contrairement à ce qu'on pourrait penser (il faut soit le forcer explicitement soit demander du -O2 ou -O3)


---------------
Si ma chaussure est étroite, que m´importe que le monde soit vaste.
n°2172562
gilou
Modérateur
Modzilla
Posté le 24-01-2013 à 23:24:52  profilanswer
 

Citation :

Bah elle a l'intérêt de fonctionner et de pas changer ses interfaces ni de rajouter une seconde fonction.

Certes, mais par rapport a la fonction itérative initiale, elle a le défaut d'empiler des appels.
La récursivité, je n'ai rien contre lorsqu'il s'agit de procédures complexes à plusieurs paramètres, mais quand ça se dérécursive de manière triviale avec un accumulateur, je n'en vois pas l'intérêt dans le contexte du C++ (on serait dans le contexte d'un langage fonctionnel, je dis pas).
A+,


---------------
Samantha Fish Rulez!     --    Iyashikei Anime Forever!    --    In umbra igitur pugnabimus. --

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  C++ liste chainée

 

Sujets relatifs
Algorithme débutant C++ adressage IP[C]Problème d'écriture avec fopen/fprintf et énumération bancale
affichage d'une liste dans une fenêtreaffichage d'une liste dans une fenêtre
Tri d'une liste doublement chainéeProxy cache en C
Bibliothèque C accès WEBpb liste chainée et lecture de fichier C
[C] Probleme swap liste double chainée[C]renverser une liste chainée
Plus de sujets relatifs à : C++ liste chainée



Copyright © 1997-2016 Hardware.fr SARL (Signaler un contenu illicite) / Groupe LDLC / Shop HFR