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 :

arbre binaire parfait


Sujet :

C++

  1. #1
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Septembre 2015
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 30
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2015
    Messages : 3
    Points : 1
    Points
    1
    Par défaut arbre binaire parfait
    Bonjour à tous

    J'essaie de créer un arbre binaire parfait en C++ et pour cela j'ai créer une classe "Noeud" et une classe "Arbre".
    Afin de traiter chaque noeud un par un, je voudrais créer une file. Pour l'instant la seule syntaxe que j'ai est : std :: queue<Type> nom_de_la_file

    Voici ma question : Est-il possible de créer une file de type "Noeud" ? Si oui, comment ?

    Merci d'avance pour votre aide !

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    Heu, c'est quoi la question ???

    Est-il possible de créer une file de type "Noeud" ?
    Heu, bin oui :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std :: queue<Noeud> nom_de_la_file;

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 631
    Points : 10 558
    Points
    10 558
    Par défaut
    @bacelar: ou bien

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class Noeud : public std::queue { // <- Or private or protected
     
    //  All stuffs here
     
    };

  4. #4
    Membre chevronné Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Points : 2 160
    Points
    2 160
    Par défaut
    Si on veut renommer un type, je ne suis pas fan d'hériter publiquement d'une classe dont le destructeur n'est pas virtuel (par principe) ; en hériter de façon privée en re-exposant l'interface n'est pas une solution élégante non plus.

    using de C++11 permet de faire le travail :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template <class T>
    using noeud = std::queue<T>;
    ---

    Pour le problème original, ta classe avec std::queue ressemblera à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    template <class T>
    class noeud
    {
    private:
    	T m_data;
    	std::queue<noeud<T>> m_children;
    public:
    	// ...
    };
    Et j'utiliserais probablement std::vector<T> au lieu de std::queue<T>.

    ---

    Et comme c'est un arbre binaire, j'utiliserais plutôt un truc qui ressemble à :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    template <class T>
    class noeud
    {
    private:
    	T m_data;
    	optional<noeud<T>> m_left;
    	optional<noeud<T>> m_right;
    public:
    	// ...
    };
    Avec optional<T> une classe qui permet d'avoir un T ou pas. Et si le T est "vide", on a le pointeur nullptr. Personnellement j'appelle cette classe optional_ptr même si optional_in_ptr ou optional_with_minimal_size_if_not serait plus juste.
    L'autre solution pour optional serait d'avoir le T serait d'avoir le T + un booléen. (Il me semble que c'est le différence entre boost::optional et std::optional.) Cette solution ici ne compilerait pas à cause de la récursivité.

  5. #5
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Septembre 2015
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 30
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2015
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Heu, bin oui :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std :: queue<Noeud> nom_de_la_file;

    C'est exactement ce que j'avais fait justement, mais ça ne compilait pas. J'ai fini par me rendre compte que le problème ce n'était pas la file en elle même mais plutôt ce que je mettais dedans...


    @Ehonn
    "Et j'utiliserais probablement std::vector<T> au lieu de std::queue<T>."

    J'aurais aussi préféré faire des vecteurs plutôt que des files mais ma prof a insisté pour qu'on fasse une file, elle disait que c'était plus adapté pour faire un arbre binaire... Mais je pense que dans tous les cas je serais obligée de faire des vecteurs quand même, sinon je ne vois pas comment je pourrais afficher mon arbre par la suite


    En tout cas merci pour vos réponses

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Avec un peu de code et le message d'erreur exact, on est meilleurs à trouver le problème.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  7. #7
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Septembre 2015
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 30
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2015
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Voici le code de ma fonction generer() et les messages d'erreurs

    ligne 23 error : 'filsg' was not declared in this scope
    ligne 24 error : 'filsd' was not declared in this scope

    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
    noeud* arbre :: generer() // cette méthode va générer l'arbre entier (la racine et les noeuds gauches et droits)
    {
        racine = creer(1); 
     
        int h; // profondeur (=hauteur) de l'arbre
        cout << "Entrer la profondeur (hauteur) de l'arbre binaire parfait : ";
        cin >> h;
     
        std :: queue<noeud> file; // file de type "noeud"
     
        while (nb_noeud < ((2^(h+1))-1)) 
        {
            int i;
            int val_gauche = 2*i;
            int val_droit = 2*i+1;
     
     
            file.push(*racine);
     
            racine->filsg = creer(val_gauche); 
            racine->filsd = creer(val_droit); 
     
            file.push(*filsg);
            file.push(*filsd);
     
            file.pop(); 
     
        }

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    - on sait pas d'où sort racine
    - tu push une copie
    - puis tu modifies l'original
    ça fait déjà un paquet de problèmes avant de savoir par quelle magie tu essayes d'assigner une valeur à des variables membres filsg et filsd qui n'existent pas.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  9. #9
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    De manière générale, un arbre binaire parfait est très difficile à obtenir, pour une raison bien simple : on ne peut l'obtenir qu'avec des nombres bien particuliers d'éléments (1, 3, 7, 15, ...). Le plus souvent, on a de la chance d'arriver à obtenir, c'est ce que l'on appelle un arbre équilibré : un arbre dans lequel il n'y a au maximum qu'un niveau d'écart entre la feuille "la plus basse" et la feuille "la plus haute" (ce qui se rapproche beaucoup plus du "cas général" ).

    Sinon, il n'y a pas vraiment de miracle: le plus sur moyen de parcourir un arbre binaire reste malgré tout d'avoir recours à la récursivité. Tu as alors trois solutions principales :

    La solution prefixe : tu commence par traitrer le noeud sur lequel tu est avant d'aller voir chacun des noeuds enfants (s'ils existent), sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    void prefix(Noeud * actuel){
        /* traiter la valeur du noeud actuelle */
        if (gauche){
            prefix(gauche);
        }
        if (droite){
            prefix(droite);
        }
    }
    la solution postfixe : tu commence par traiter les noeuds enfants (s'ils existent) avant de traiter le noeud actuel, sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    void postfix(Noeud * actuel){
        if (gauche){
            postfix(gauche);
        }
        if (droite){
            postfix(droite);
        }
        /* traiter la valeur du noeud actuelle */
    }
    et enfin la solution infixe : tu traites d'abord l'un des noeuds enfant( s'il existe, bien sur), puis tu traites la valeurs du noeud courant, et enfin tu traite l'autre noeud enfant( s'il existe, bien sur) sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void infix(Noeud * actuel){
        if (gauche){
            infix(gauche);
        }
        /* traiter la valeur du noeud actuelle */
        if (droite){
            infix(droite);
        }
    }
    Une fois que tu as ces trois schémas en tête, il t'appartient de savoir ce que tu veux faire afin de pouvoir choisir celui qui correspond à ta situation

    NOTA: il t'est, bien sur, toujours possible d'inverser l'ordre de traitement gauche/droite, selon tes besoins réels
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. Arbre binaire parfait
    Par j0o0 dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 03/11/2011, 09h27
  2. Afficher un arbre binaire avec sa structure
    Par PhoneKilleR dans le forum C
    Réponses: 7
    Dernier message: 23/04/2008, 23h24
  3. [Arbre binaire de Recherche]
    Par Giovanny Temgoua dans le forum Algorithmes et structures de données
    Réponses: 11
    Dernier message: 06/02/2004, 11h45
  4. Arbre binaire
    Par Heaven dans le forum Algorithmes et structures de données
    Réponses: 6
    Dernier message: 02/02/2004, 19h01
  5. [LG]probleme de creation arbre binaire
    Par jsaviola dans le forum Langage
    Réponses: 2
    Dernier message: 06/01/2004, 20h57

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