CTree

La classe CTree est un arbre binaire d'instances de classe CTreeNode et de ses descendants.

Description

La classe CTree permet de travailler avec un arbre binaire d'instances de la classe CTreeNode et de ses descendants. Les méthodes d'ajout, insertion et suppression des éléments et de recherche dans l'arbre sont implémentées dans cette classe. Elle implémente également les méthodes permettant de travailler avec les fichiers.

Noter que le mécanisme de gestion de la mémoire n'est pas implémenté dans la classe CTree (contrairement aux classes CList et CArrayObj). Tous les noeuds de l'arbre sont supprimés et la mémoire libérée.

Déclaration

   class CTree : public CTreeNode

Titre

   #include <Arrays\Tree.mqh>

Hiérarchie d'héritage

  CObject

      CTreeNode

          CTree

Méthodes de Classe

Attributs

 

Root

Retourne le noeud racine de l'arbre

Création d'u nouvel élément

 

CreateElement

Création d'un nouveau noeud

Remplissage

 

Insert

Ajout d'un noeud à un arbre

Suppression

 

Detach

Détache de l'arbre un noeud spécifié

Delete

Supprime de l'arbre un noeud spécifié

Clear

Supprime tous les noeuds de l'arbre

Recherche

 

Find

Recherche un noeud dans l'arbre à partir d'un modèle

Entrée/Sortie

 

virtual Save

Sauvegarde les données de l'arbre dans un fichier

virtual Load

Charge les données d'un arbre depuis un fichier

virtual Type

Retourne l'identifiant du type de l'arbre

Méthodes héritées de la classe CObject

Prev, Prev, Next, Next, Compare

Méthodes héritées de la classe CTreeNode

Parent, Parent, Left, Left, Right, Right, Balance, BalanceL, BalanceR, RefreshBalance, GetNext, SaveNode, LoadNode

Les arbres de classes CTreeNode dérivant de CTree sont mis en application.

Les classes filles de la classe CTree doivent implémenter la méthode prédéfinie CreateElement qui crée un nouveau CTreeNode.

Considérons l'exemple d'une classe dérivée de la classe CTree.

//+------------------------------------------------------------------+
//|                                                       MyTree.mq5 |
//|                         Copyright 2000-2024, MetaQuotes Ltd. |
//| www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//---
#include <Arrays\Tree.mqh>
#include "MyTreeNode.mqh"
//---
input int extCountedNodes = 100;
//+------------------------------------------------------------------+
//| Describe class CMyTree derived from CTree. |
//+------------------------------------------------------------------+
//| Class CMyTree.                                                   |
//| But : Construction et navigation d'une recherche binaire dans un arbre. |
//+------------------------------------------------------------------+
class CMyTree : public CTree
  {
public:
   //--- méthode de recherche dans l'arbre à partir de données spécifiques
   CMyTreeNode*        FindByLong(long find_long);
   //--- méthode de création de l'élément dans l'arbre
   virtual CTreeNode *CreateElement();
  };
//---
CMyTree MyTree;
//+------------------------------------------------------------------+
//| Création d'un nouveau noeud dans l'arbre. |
//| ENTREE :  aucun. |
//| SORTIE : pointeur vers le nouveau noeud de l'arbre en cas de succès, sinon NULL. |
//| REMARQUE : aucune. |
//+------------------------------------------------------------------+
CTreeNode *CMyTree::CreateElement()
  {
   CMyTreeNode *node=new CMyTreeNode;
//---
   return(node);
  }
//+------------------------------------------------------------------+
//| Cherche un élément à partir d'une valeur m_long. |
//| ENTREE :  find_long - valeur recherchée. |
//| SORTIE : pointeur sur l'élément trouvé, ou NULL. |
//| REMARQUE : aucune. |
//+------------------------------------------------------------------+
CMyTreeNode* CMyTree::FindByLong(long find_long)
  {
   CMyTreeNode *res=NULL;
   CMyTreeNode *node;
//--- crée un nouveau noeud pour passer le paramètre de recherche
   node=new CMyTreeNode;
   if(node==NULLreturn(NULL);
   node.SetLong(find_long);
//---
   res=Find(node);
   delete node;
//---
   return(res);
  }
//+------------------------------------------------------------------+
//| script "test de la class CMyTree"                                |
//+------------------------------------------------------------------+
//---  tableau de chaînes d'initialisation
string str_array[11]={"p","oo","iii","uuuu","yyyyy","ttttt","rrrr","eee","ww","q","999"};
//---
int OnStart() export
  {
   int          i;
   uint         pos;
   int          beg_time,end_time;
   CMyTreeNode *node; //--- pointeur temporaire vers le modèle de la classe CMyTreeNode 
//---  
   printf("Start test %s.",__FILE__);
//--- Remplissage de MyTree avec les modèles de classe MyTreeNode.
   beg_time=GetTickCount();
   for(i=0;i<extCountedNodes;i++)
     {
      node=MyTree.CreateElement();
      if(node==NULL)
        {
         //--- sortie d'urgence
         printf("%s (%4d): create error",__FILE__,__LINE__);
         return(__LINE__);
        }
      NodeSetData(node,i);
      node.SetLong(i);
      MyTree.Insert(node);
     }
   end_time=GetTickCount();
   printf("Filling time of MyTree is %d ms.",end_time-beg_time);
//--- Crée un arbre temporaire TmpMyTree.
   CMyTree TmpMyTree;
//--- Détache 50% des éléments de l'arbre (tous les noeuds ayant une valeur paire)
//--- et les ajoute à la table temporaire TmpMyTree.
   beg_time=GetTickCount();
   for(i=0;i<extCountedNodes;i+=2)
     {
      node=MyTree.FindByLong(i);
      if(node!=NULL)
         if(MyTree.Detach(node)) TmpMyTree.Insert(node);
     }
   end_time=GetTickCount();
   printf("Deletion time of %d elements from MyTree is %d ms.",extCountedNodes/2,end_time-beg_time);
//--- Retourne l'élément détaché
   node=TmpMyTree.Root();
   while(node!=NULL)
     {
      if(TmpMyTree.Detach(node)) MyTree.Insert(node);
      node=TmpMyTree.Root();
     }
//--- Appelle et vérifie la méthode Save(int file_handle);
   int file_handle;
   file_handle=FileOpen("MyTree.bin",FILE_WRITE|FILE_BIN|FILE_ANSI);
   if(file_handle>=0)
     {
      if(!MyTree.Save(file_handle))
        {
         //--- erreur d'écriture dans le fichier
         //--- sortie d'urgence
         printf("%s: Error %d in %d!",__FILE__,GetLastError(),__LINE__);
         //--- fermeture du fichier avant de quitter !!!
         FileClose(file_handle);
         return(__LINE__);
        }
      FileClose(file_handle);
     }
//--- Appelle et vérifie la méthode Load(int file_handle);
   file_handle=FileOpen("MyTree.bin",FILE_READ|FILE_BIN|FILE_ANSI);
   if(file_handle>=0)
     {
      if(!TmpMyTree.Load(file_handle))
        {
         //--- erreur de lecture du fichier
         //--- sortie d'urgence
         printf("%s: Error %d in %d!",__FILE__,GetLastError(),__LINE__);
         //--- fermeture du fichier avant de quitter !!!
         FileClose(file_handle);
         return(__LINE__);
        }
      FileClose(file_handle);
     }
//---
   MyTree.Clear();
   TmpMyTree.Clear();
//---
   printf("End test %s. OK!",__FILE__);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Fonction de journalisation du contenu d'un noeud |
//+------------------------------------------------------------------+
void NodeToLog(CMyTreeNode *node)
  {
   printf("   %I64d,%f,'%s','%s'",
               node.GetLong(),node.GetDouble(),
               node.GetString(),TimeToString(node.GetDateTime()));
  }
//+------------------------------------------------------------------+
//| Fonction de "remplissage" d'un noeud avec des valeurs aléatoires |
//+------------------------------------------------------------------+
void NodeSetData(CMyTreeNode *node,int mode)
  {
   if(mode%2==0)
     {
      node.SetLong(mode*MathRand());
      node.SetDouble(MathPow(2.02,mode)*MathRand());
     }
   else
     {
      node.SetLong(mode*(long)(-1)*MathRand());
      node.SetDouble(-MathPow(2.02,mode)*MathRand());
     }
   node.SetString(str_array[mode%10]);
   node.SetDateTime(10000*mode);
  }