MobinMQL/Include/Arrays/TreeNode.mqh
2025-07-22 14:47:41 +03:00

174 lines
6.5 KiB
MQL5

//+------------------------------------------------------------------+
//| TreeNode.mqh |
//| Copyright 2000-2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#include <Object.mqh>
//+------------------------------------------------------------------+
//| Class CTreeNode. |
//| Purpose: Base class of node of binary tree CTree. |
//| Derives from class CObject. |
//+------------------------------------------------------------------+
class CTreeNode : public CObject
{
private:
CTreeNode *m_p_node; // link to node up
CTreeNode *m_l_node; // link to node left
CTreeNode *m_r_node; // link to node right
//--- variables
int m_balance; // balance of node
int m_l_balance; // balance of the left branch
int m_r_balance; // balance of the right branch
public:
CTreeNode(void);
~CTreeNode(void);
//--- methods of access to protected data
CTreeNode* Parent(void) const { return(m_p_node); }
void Parent(CTreeNode *node) { m_p_node=node; }
CTreeNode* Left(void) const { return(m_l_node); }
void Left(CTreeNode *node) { m_l_node=node; }
CTreeNode* Right(void) const { return(m_r_node); }
void Right(CTreeNode *node) { m_r_node=node; }
int Balance(void) const { return(m_balance); }
int BalanceL(void) const { return(m_l_balance); }
int BalanceR(void) const { return(m_r_balance); }
//--- method of identifying the object
virtual int Type(void) const { return(0x8888); }
//--- methods for controlling
int RefreshBalance(void);
CTreeNode *GetNext(const CTreeNode *node);
//--- methods for working with files
bool SaveNode(const int file_handle);
bool LoadNode(const int file_handle,CTreeNode *main);
protected:
//--- method for creating an instance of class
virtual CTreeNode *CreateSample(void) { return(NULL); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CTreeNode::CTreeNode(void) : m_p_node(NULL),
m_l_node(NULL),
m_r_node(NULL),
m_balance(0),
m_l_balance(0),
m_r_balance(0)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CTreeNode::~CTreeNode(void)
{
//--- delete nodes of the next level
if(m_l_node!=NULL)
delete m_l_node;
if(m_r_node!=NULL)
delete m_r_node;
}
//+------------------------------------------------------------------+
//| Calculating the balance of the node |
//+------------------------------------------------------------------+
int CTreeNode::RefreshBalance(void)
{
//--- calculate the balance of the left branch
if(m_l_node==NULL)
m_l_balance=0;
else
m_l_balance=m_l_node.RefreshBalance();
//--- calculate the balance of the right branch
if(m_r_node==NULL)
m_r_balance=0;
else
m_r_balance=m_r_node.RefreshBalance();
//--- calculate the balance of the node
if(m_r_balance>m_l_balance)
m_balance=m_r_balance+1;
else
m_balance=m_l_balance+1;
//--- result
return(m_balance);
}
//+------------------------------------------------------------------+
//| Selecting next node |
//+------------------------------------------------------------------+
CTreeNode *CTreeNode::GetNext(const CTreeNode *node)
{
if(Compare(node)>0)
return(m_l_node);
//--- result
return(m_r_node);
}
//+------------------------------------------------------------------+
//| Writing node data to file |
//+------------------------------------------------------------------+
bool CTreeNode::SaveNode(const int file_handle)
{
bool result=true;
//--- check
if(file_handle==INVALID_HANDLE)
return(false);
//--- write left node (if it is available)
if(m_l_node!=NULL)
{
FileWriteInteger(file_handle,'L',SHORT_VALUE);
result&=m_l_node.SaveNode(file_handle);
}
else
FileWriteInteger(file_handle,'X',SHORT_VALUE);
//--- write data of current node
result&=Save(file_handle);
//--- write right node (if it is available)
if(m_r_node!=NULL)
{
FileWriteInteger(file_handle,'R',SHORT_VALUE);
result&=m_r_node.SaveNode(file_handle);
}
else
FileWriteInteger(file_handle,'X',SHORT_VALUE);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Reading node data from file |
//+------------------------------------------------------------------+
bool CTreeNode::LoadNode(const int file_handle,CTreeNode *main)
{
bool result=true;
short s_val;
CTreeNode *node;
//--- check
if(file_handle==INVALID_HANDLE)
return(false);
//--- read directions
s_val=(short)FileReadInteger(file_handle,SHORT_VALUE);
if(s_val=='L')
{
//--- read left node (if there is data)
node=CreateSample();
if(node==NULL)
return(false);
m_l_node=node;
node.Parent(main);
result&=node.LoadNode(file_handle,node);
}
//--- read data of current node
result&=Load(file_handle);
//--- read directions
s_val=(short)FileReadInteger(file_handle,SHORT_VALUE);
if(s_val=='R')
{
//--- read right node (if there is data)
node=CreateSample();
if(node==NULL)
return(false);
m_r_node=node;
node.Parent(main);
result&=node.LoadNode(file_handle,node);
}
//--- result
return(result);
}
//+------------------------------------------------------------------+