CTree

CTree è una classe di albero binario delle istanze della classe CTreeNode e dei suoi discendenti.

Descrizione

La Classe Ctree offre la possibilità di lavorare con l'albero binario di istanze della classe CTreeNode e dei suoi discendenti. Opzioni di aggiunta/inserimento/cancellazione di elementi albero e ricerca nell' albero vengono implementati nella classe. Oltre a questo, vengono implementati i metodi di lavoro con un file.

Si noti che il meccanismo di gestione della memoria dinamica non è implementato nella classe Ctree (a differenza della classi CList e CArrayObj). Tutti i nodi dell'albero vengono cancellati con la deallocazione di memoria.

Dichiarazione

   class CTree : public CTreeNode

Titolo

   #include <Arrays\Tree.mqh>

Gerarchia di ereditarietà

  CObject

      CTreeNode

          CTree

I Metodi della Classe per Gruppi

Attributi

 

Root

Ottiene il nodo radice(root) dell'albero

Creazione di un nuovo elemento

 

CreateElement

Crea una nuova istanza del nodo

Filling

 

Insert

Aggiunge un nodo ad un albero

Eliminazione

 

Detach

Distacca un nodo specificato da un albero

Delete

Elimina un nodo specificato da un albero

Clear

Elimina tutti i nodi di un albero

Ricerca

 

Find

Ricerche per un nodo in un albero per campione

Input/output

 

virtual Save

Salva tutti i dati di un albero in un file

virtual Load

Scarica i dati di un albero da un file

virtual Type

Ottiene identificativo del tipo di albero

Metodi ereditati dalla classe CObject

Prev, Prev, Next, Next, Compare

Metodi ereditati dalla classe CTreeNode

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

Alberi dei discendenti della classe CTreeNode - discendenti della classe Ctree - hanno applicazione pratica.

Discendente della classe Ctree dovrebbero avere un metodo predefinito CreateElement che crea una nuova istanza della classe discendente CTreeNode.

Prendiamo in considerazione un esempio della classe discendente 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;
//+------------------------------------------------------------------+
//| Descrive la classe CMyTree derivata da CTree.                       |
//+------------------------------------------------------------------+
//| Classe CMyTree.                                                   |
//| Scopo: Costruzione e navigazione di una ricerca albero binario.    |
//+------------------------------------------------------------------+
class CMyTree : public CTree
  {
public:
   //--- medoti di ricerca nell'albero da dati personalizzati
   CMyTreeNode*        FindByLong(long find_long);
   //--- metodo di creazione di elementi dell'albero
   virtual CTreeNode *CreateElement();
  };
//---
CMyTree MyTree;
//+------------------------------------------------------------------+
//| Creazione di un nuovo nodo albero.                                     |
//| INPUT:  niente.                                                    |
//| OUTPUT: puntatore al nuovo nodo albero se OK, o NULL.             |
//| REMARK: niente.                                                    |
//+------------------------------------------------------------------+
CTreeNode *CMyTree::CreateElement()
  {
   CMyTreeNode *node=new CMyTreeNode;
//---
   return(node);
  }
//+------------------------------------------------------------------+
//| Ricerca di elemento in una lista per valore m_long.                     |
//| INPUT:  find_long - valore cercato.                              |
//| OUTPUT: puntatore all'elemento della lista trovato, oppure NULL.                |
//| REMARK: niente.                                                    |
//+------------------------------------------------------------------+
CMyTreeNode* CMyTree::FindByLong(long find_long)
  {
   CMyTreeNode *res=NULL;
   CMyTreeNode *node;
//--- crea un nodo della struttura per passare il parametro di ricerca
   node=new CMyTreeNode;
   if(node==NULLreturn(NULL);
   node.SetLong(find_long);
//---
   res=Find(node);
   delete node;
//---
   return(res);
  }
//+------------------------------------------------------------------+
//| script "testing della classe CMyTree"                            |
//+------------------------------------------------------------------+
//---  array per l'inizializzazione stringa
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; //--- puntatore temporaneo al campione della classe CMyTreeNode 
//---  
   printf("Inizio test %s.",__FILE__);
// --- Compila MyTree con istanze della classe MyTreeNode nella quantità di extCountedNodes.
   beg_time=GetTickCount();
   for(i=0;i<extCountedNodes;i++)
     {
      node=MyTree.CreateElement();
      if(node==NULL)
        {
         //--- uscita di emergenza
         printf("%s (%4d): crea errore",__FILE__,__LINE__);
         return(__LINE__);
        }
      NodeSetData(node,i);
      node.SetLong(i);
      MyTree.Insert(node);
     }
   end_time=GetTickCount();
   printf("Tempo di ricerca di MyTree è di %d ms.",end_time-beg_time);
//--- Crea un albero TmpMyTree temporaneo.
   CMyTree TmpMyTree;
//--- Distacca il 50% degli elementi di albero (tutti pari)
//--- e li aggiunger allalbero temporaneo 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("Tempo di eliminazione di %d elementi da MyTree è di %d ms.",extCountedNodes/2,end_time-beg_time);
//--- Restituisce il distaccamento
   node=TmpMyTree.Root();
   while(node!=NULL)
     {
      if(TmpMyTree.Detach(node)) MyTree.Insert(node);
      node=TmpMyTree.Root();
     }
//--- Controlla il lavoro del metodo 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))
        {
         //--- errore di scrittura in un file
         //--- uscita di emergenza
         printf("%s: Errore %d in %d!",__FILE__,GetLastError(),__LINE__);
         //--- chiusura file prima di lasciarlo!!!
         FileClose(file_handle);
         return(__LINE__);
        }
      FileClose(file_handle);
     }
//--- Controlla il lavoro del metodo Load(int file_handle);
   file_handle=FileOpen("MyTree.bin",FILE_READ|FILE_BIN|FILE_ANSI);
   if(file_handle>=0)
     {
      if(!TmpMyTree.Load(file_handle))
        {
         //--- errore di lettura dal file
         //--- uscita di emergenza
         printf("%s: Errore %d in %d!",__FILE__,GetLastError(),__LINE__);
         //--- chiusura file prima di lasciarlo!!!
         FileClose(file_handle);
         return(__LINE__);
        }
      FileClose(file_handle);
     }
//---
   MyTree.Clear();
   TmpMyTree.Clear();
//---
   printf("Fine test %s. OK!",__FILE__);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Funzione per dare in output il contenuto nodo nel journal |
//+------------------------------------------------------------------+
void NodeToLog(CMyTreeNode *node)
  {
   printf("   %I64d,%f,'%s','%s'",
               node.GetLong(),node.GetDouble(),
               node.GetString(),TimeToString(node.GetDateTime()));
  }
//+------------------------------------------------------------------+
//| Funzione per popolare il nodo con valori casuali |
//+------------------------------------------------------------------+
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);
  }