Chronoklazm | Yo,
Alors voilà j'ai fait ma petite classe ABR générique qui marche pas trop mal, manque plus que des trucs tordus genre les fonctions de réequilibrage de l'arbre.
Je poste surtout ce code pour entendre des critiques sur ma façon de m'y prendre (je suis un noob en C++), histoire d'éviter les mauvaises habitudes.
J'ai surement oublié grave de trucs.
PS : Taz, tappe pas trop fort stp La classe Noeud (bon là cash il y a un gros defaut c'est *fils_gauche et *fils_droit qui sont en public, bein oué ... faudrai que je change apres) :
La classe ABR :
Code :
- //Fichier ABR.h
- #include <cstdlib>
- #include <iostream>
- #include <vector>
- #include "Noeud.h"
- using namespace std;
- //Declaration de la classe ABR
- template <class Type> class ABR;
- //Declaration de la fonction de surcharge de <<
- template <class Type>
- ostream &operator<<(ostream &o, const ABR<Type> &a);
- //Declaration de la classe ABR
- template <class Type>
- class ABR
- {
- //Et oui je sais que c'est laid mais c'est comme ca !!
- friend ostream &operator<< <>(ostream &o, const ABR<Type> &a);
-
- Noeud<Type> *racine;
-
- public:
- ABR();
- ABR(Type el);
- ABR(Noeud<Type> *n);
- //Destructeur
- ~ABR();
- //Accesseur
- Noeud<Type> *get_racine();
- //Consultation
- bool consulter(Type el);
- //Insertion d'un element
- bool inserer(Type el);
- //Insertion d'un sous arbre
- void inserer_arbre(const ABR<Type> &a);
- //Effacer
- bool effacer(Type el);
- //Effacement de this
- void effacer();
- //Affichage
- void dump(ostream &o);
- //Remplissage d'un vector
- void rempl(Noeud<Type> *n, vector<Type> &v);
- //Affichage normal
- void affiche(Noeud<Type> *n, ostream &o);
- //Affichage trie
- void trie_affiche(ostream &o);
- //Cloner l'arbre passé en param
- ABR<Type> clone(const ABR<Type> &a);
- //Cloner l'arbre courant
- ABR<Type> clone();
- };
- //Constructeur sans params
- template <class Type>
- ABR<Type>::ABR()
- {
- racine = NULL;
- };
- //Constructeur avec el
- template <class Type>
- ABR<Type>::ABR(Type el)
- {
- racine = new Noeud<Type>(el);
- };
- //Constructeur avec un ptr sur noeud
- template <class Type>
- ABR<Type>::ABR(Noeud<Type> *n)
- {
- racine = n;
- };
- //Destructeur
- template <class Type>
- ABR<Type>::~ABR()
- {
- racine->effacer(racine);
- };
- //Accesseur pour la racine
- template <class Type>
- Noeud<Type> *ABR<Type>::get_racine()
- {
- return racine;
- };
- //Consultation
- //Renvoi un booleen si l'element est present
- template <class Type>
- bool ABR<Type>::consulter(Type el)
- {
- Noeud<Type> *actuel = racine;
- while(actuel)
- {
- if(actuel->get_element() == el)
- return true;
- else
- if(actuel->get_element() < el)
- actuel = actuel->fils_gauche;
- else
- actuel = actuel->fils_droit;
- }
- return false;
- };
- //Insertion
- template <class Type>
- bool ABR<Type>::inserer(Type el)
- {
- Noeud<Type> **actuel = &racine;
- while(*actuel){
- //Si on est dessus on fait rien
- if((*actuel)->get_element() == el){
- return 0;
- }else{
- //Si notre el est inf a element de la racine
- //on va a gauche
- if(el < (*actuel)->get_element()){
- actuel = &((*actuel)->fils_gauche);
- }else{
- actuel = &((*actuel)->fils_droit);
- }
- }
- }
- //On crée un nouveau noeud
- *actuel = new Noeud<Type>(el);
- return 1;
- };
- //Insertion d'un sous-arbre
- template <class Type>
- void ABR<Type>::inserer_arbre(const ABR<Type> &a)
- {
- //Variable d'adresse pour parcourir l'arbre courant
- Noeud<Type> **actuel = &(racine);
- //Element de la racine de l'arbre a inserer
- Type el = (a.racine)->get_element();
- while(*actuel){
- //Si on est dessus on insere (bourrinage)
- if((*actuel)->get_element() == el){
- *actuel = (a.racine)->clone();
- }else{
- //Si notre el est inf a element de la racine
- //on va a gauche
- if(el < (*actuel)->get_element()){
- actuel = &((*actuel)->fils_gauche);
- }else{
- actuel = &((*actuel)->fils_droit);
- }
- }
- }
- //Insertion du sous arbre
- *actuel = (a.racine)->clone();
- };
- //Methode pour effacer un element (ne racorde pas les noeuds fils)
- template <class Type>
- bool ABR<Type>::effacer(Type el)
- {
- Noeud<Type> **actuel = &racine;
- while(*actuel){
- //Si on est dessus on fait rien
- if((*actuel)->get_element() == el){
- //On efface le noeud
- delete(*actuel);
- return true;
- }else{
- //Si notre el est inf a element de la racine
- //on va a gauche
- if(el < (*actuel)->get_element()){
- actuel = &((*actuel)->fils_gauche);
- }else{
- actuel = &((*actuel)->fils_droit);
- }
- }
- }
- return false;
- }
- //Methode pour l'affichage triée, sera heritee
- template <class Type>
- void ABR<Type>::rempl(Noeud<Type> *n, vector<Type> &v)
- {
- if(n != NULL){
- v.push_back(n->get_element());
- if(n->fils_gauche != NULL)
- rempl(n->fils_gauche, v);
-
- if(n->fils_droit != NULL)
- rempl(n->fils_droit, v);
- }
- };
- //Affichage normal
- template <class Type>
- void ABR<Type>::affiche(Noeud<Type> *n, ostream &o)
- {
- o << "[" << n->get_element() << " : " ;
- o << ((n->fils_gauche != NULL) ? (n->fils_gauche)->get_element() : (Type)NULL) << ", ";
- o << ((n->fils_droit != NULL) ? (n->fils_droit)->get_element() : (Type)NULL) << "]" << endl;
- if(n->fils_gauche != NULL){
- affiche(n->get_fg(), o);
- }
- if(n->fils_droit != NULL){
- affiche(n->get_fd(), o);
- }
- };
- //Methode pour trier et afficher l'arbre
- template <class Type>
- void ABR<Type>::trie_affiche(ostream &o)
- {
- //Declaration
- vector<Type> vec;
- //Remplissage
- rempl(racine, vec);
- //Tri du vector
- sort(vec.begin(), vec.end());
- o << "\n" << endl;
- for(int i = 0; i<vec.size(); i++){
- o << vec[i] << " ";
- }
- o << endl;
- };
- //Methode pour l'affichage (sera heritee)
- template <class Type>
- void ABR<Type>::dump(ostream &o)
- {
- //Affichage normal
- affiche(racine, o);
- //Affichage triée
- trie_affiche(o);
- };
- //Methode pour cloner un arbre
- template <class Type>
- ABR<Type> ABR<Type>::clone(const ABR<Type> &a)
- {
- //Creation d'un noeud bidon
- Noeud<Type> bidon(0);
- //Creation de l'arbre a renvoyer
- ABR<Type> res(bidon.clone(a.racine));
- return res;
- }
- //Methode pour cloner this
- template <class Type>
- ABR<Type> ABR<Type>::clone()
- {
- //Creation d'un noeud bidon
- Noeud<Type> bidon(0);
- //Creation de l'arbre a renvoyer
- ABR<Type> res(bidon.clone(this->racine));
- return res;
- }
- //Surcharge de <<
- template <class Type>
- ostream &operator<<(ostream &o, const ABR<Type> &a)
- {
- o << "AFFICHAGE DE l'ARBRE : " << endl;
- //Creation d'un noeud bidon
- Noeud<Type> bidon(0);
- //Creation d'un arbre temporaire
- ABR<Type> temp(bidon.clone(a.racine));
- temp.dump(o);
- return o;
- };
|
Le petit main :
Code :
- #include <cstdlib>
- #include <iostream>
- #include "ABR.h"
- using namespace std;
- int main(int argc, char *argv[])
- {
- // TEST DE LA CLASSE ABR
- ABR<int> arbre_int(3);
- cout << "arbre_int.inserer(4) : " << arbre_int.inserer(4) << endl;
- cout << "arbre_int.inserer(5) : " << arbre_int.inserer(5) << endl;
- cout << "arbre_int.inserer(1) : " << arbre_int.inserer(1) << endl;
- cout << "arbre_int.inserer(2) : " << arbre_int.inserer(2) << endl;
- cout << arbre_int << endl;
-
- ABR<float> arbre_float(9);
- cout << "arbre_float.inserer(4) : " << arbre_float.inserer(4) << endl;
- cout << "arbre_float.inserer(5) : " << arbre_float.inserer(5) << endl;
- cout << "arbre_float.inserer(1) : " << arbre_float.inserer(1) << endl;
- cout << "arbre_float.inserer(2) : " << arbre_float.inserer(2) << endl;
- cout << arbre_float << endl;
-
- //Test du clonage
- ABR<float> t = arbre_float.clone();
- cout << t << endl;
-
- //Test de l'insertion d'un sous-arbre
- cout << "\nTEST DE L'INSERTION D'UN SOUS ARBRE :\n" << endl;
- ABR<short> a;
- cout << "a.inserer(4) : " << a.inserer(4) << endl;
- cout << "a.inserer(5) : " << a.inserer(5) << endl;
- cout << "a.inserer(9) : " << a.inserer(9) << endl;
-
- ABR<short> b;
- cout << "b.inserer(1) : " << b.inserer(1) << endl;
- cout << "b.inserer(6) : " << b.inserer(6) << endl;
- cout << "b.inserer(8) : " << b.inserer(8) << endl;
-
- cout << "a.inserer_arbre(b) : " << endl;
- a.inserer_arbre(b);
-
- cout << a << endl;
-
- system("PAUSE" );
- return EXIT_SUCCESS;
- }
|
Ca compile et s'execute sans probs du moins avec ces quelques ptits tests dans le main. ---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
|