CTree

La clase CTree proporciona un árbol binario de instancias de la clase CTreeNode, e instancias de clases hijas descendientes.

Descripción

La clase CTree permite trabajar con un árbol binario de instancias de CTreeNode, e instancias de clases hijas descendientes. Esta clase implementa opciones para añadir, insertar y borrar elementos del árbol, así como buscarlos. Además de lo anterior, también posibilita trabajar con archivos.

Cabe señalar que CTree no implementa ningún mecanismo para gestionar la memoria dinámica (a diferencia de las clases CList y CArrayObj). Cuando se libera la memoria, todos los nodos del árbol son eliminados.

Declaración

   class CTree : public CTreeNode

Título

   #include <Arrays\Tree.mqh>

Jerarquía de herencia

  CObject

      CTreeNode

          CTree

Métodos de la clase

Atributos

 

Root

Obtiene el nodo raíz del árbol

Creación de un elemento nuevo

 

CreateElement

Crea un nuevo nodo

Relleno

 

Insert

Añade un nodo al árbol

Borrado

 

Detach

Quita el nodo especificado del árbol

Delete

Borra el nodo especificado del árbol

Clear

Borra todos los elementos del árbol

Búsqueda

 

Find

Busca el nodo de acuerdo a la muestra especificada

Entrada/salida

 

virtual Save

Guarda los datos del árbol en el archivo

virtual Load

Descarga los datos del árbol del archivo

virtual Type

Obtiene el identificador de tipo del árbol

Métodos heredados de la clase CObject

Prev, Prev, Next, Next, Compare

Métodos heredados de la clase CTreeNode

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

Árboles de la clase CTreeNode — los descendientes de la clase CTree tienen aplicación práctica.

Los descendientes de la clase CTree deben implementar el método predefinido CreateElement que crea una nueva muestra de la clase descendiente CTreeNode.

Consideremos ahora un ejemplo de clase descendiente de 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 la clase CMyTree, descendiente de CTree.                       |
//+------------------------------------------------------------------+
//| Clase CMyTree.                                                   |
//| Objetivo: Construcción de un árbol binario de búsqueda y navegación.    |
//+------------------------------------------------------------------+
class CMyTree : public CTree
  {
public:
   //--- métodos para buscar en el árbol los datos especificados
   CMyTreeNode*        FindByLong(long find_long);
   //--- método que crea un nuevo elemento
   virtual CTreeNode *CreateElement();
  };
//---
CMyTree MyTree;
//+------------------------------------------------------------------+
//| Creación de un nuevo nodo en el árbol.                                     |
//| INPUT:  ninguna.                                                    |
//| Salida: puntero a un nuevo nodo del árbol si se ejecuta correctamente, o NULL.             |
//| Observaciones: ninguna.                                                    |
//+------------------------------------------------------------------+
CTreeNode *CMyTree::CreateElement()
  {
   CMyTreeNode *node=new CMyTreeNode;
//---
   return(node);
  }
//+------------------------------------------------------------------+
//| Búsqueda de un elemento en la lista por valor m_long.                     |
//| INPUT:  find_long - valor buscado.                              |
//| OUTPUT: puntero al elemento encontrado en la lista, o NULL.                |
//| Observaciones: ninguna.                                                    |
//+------------------------------------------------------------------+
CMyTreeNode* CMyTree::FindByLong(long find_long)
  {
   CMyTreeNode *res=NULL;
   CMyTreeNode *node;
//--- crea un nodo en el árbol para pasar el parámetro de búsqueda
   node=new CMyTreeNode;
   if(node==NULLreturn(NULL);
   node.SetLong(find_long);
//---
   res=Find(node);
   delete node;
//---
   return(res);
  }
//+------------------------------------------------------------------+
//| script "pruebas con la clase CMyTree"                            |
//+------------------------------------------------------------------+
//---  inicialización de las cadenas de texto
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; //--- puntero temporal a la muestra de la clase CMyTreeNode 
//---  
   printf("Comienzo de las pruebas %s.",__FILE__);
//--- Llenar MyTree con muestras de la clase MyTreeNode en la cantidad de extCountedNodes.
   beg_time=GetTickCount();
   for(i=0;i<extCountedNodes;i++)
     {
      node=MyTree.CreateElement();
      if(node==NULL)
        {
         //--- salida de emergencia
         printf("%s (%4d): error en la creación",__FILE__,__LINE__);
         return(__LINE__);
        }
      NodeSetData(node,i);
      node.SetLong(i);
      MyTree.Insert(node);
     }
   end_time=GetTickCount();
   printf("El tiempo de llenado de MyTree es %d ms.",end_time-beg_time);
//--- Crear un árbol temporal TmpMyTree.
   CMyTree TmpMyTree;
//--- Quita el 50% de los elementos del árbol (incluso todos)
//--- añadir elementos al árbol temporal 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("El tiempo de borrado de %d elementos de MyTree es %d ms.",extCountedNodes/2,end_time-beg_time);
//--- Devuelve los quitados
   node=TmpMyTree.Root();
   while(node!=NULL)
     {
      if(TmpMyTree.Detach(node)) MyTree.Insert(node);
      node=TmpMyTree.Root();
     }
//--- Comprobar el trabajo del método Save(int file_handle);
   int file_handle;
   file_handle=FileOpen("MiArbol.bin",FILE_WRITE|FILE_BIN|FILE_ANSI);
   if(file_handle>=0)
     {
      if(!MyTree.Save(file_handle))
        {
         //--- error al escribir en el archivo
         //--- salida de emergencia
         printf("%s: Error %d en %d!",__FILE__,GetLastError(),__LINE__);
         //--- cerrar el archivo antes de terminar!!!
         FileClose(file_handle);
         return(__LINE__);
        }
      FileClose(file_handle);
     }
//--- Comprobar el trabajo del método Load(int file_handle);
   file_handle=FileOpen("MiArbol.bin",FILE_READ|FILE_BIN|FILE_ANSI);
   if(file_handle>=0)
     {
      if(!TmpMyTree.Load(file_handle))
        {
         //--- error al leer del archivo
         //--- salida de emergencia
         printf("%s: Error %d en %d!",__FILE__,GetLastError(),__LINE__);
         //--- cerrar el archivo antes de terminar!!!
         FileClose(file_handle);
         return(__LINE__);
        }
      FileClose(file_handle);
     }
//---
   MyTree.Clear();
   TmpMyTree.Clear();
//---
   printf("Finalizar test %s. OK!",__FILE__);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Función que genera el contenido del nodo                   |
//+------------------------------------------------------------------+
void NodeToLog(CMyTreeNode *node)
  {
   printf("   %I64d,%f,'%s','%s'",
               node.GetLong(),node.GetDouble(),
               node.GetString(),TimeToString(node.GetDateTime()));
  }
//+------------------------------------------------------------------+
//| Función que llena el nodo con valores aleatorios                 |
//+------------------------------------------------------------------+
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);
  }