//+------------------------------------------------------------------+
//| 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;
//+------------------------------------------------------------------+
//| CTree에서 파생된 CMyTree 클래스를 설명합니다. |
//+------------------------------------------------------------------+
//| Class CMyTree. |
//| 목적: 이진 검색 트리의 구성 및 탐색. |
//+------------------------------------------------------------------+
class CMyTree : public CTree
{
public:
//--- 사용자 정의 데이터로 트리에서 검색하는 방법
CMyTreeNode* FindByLong(long find_long);
//--- 트리 요소 생성 방법
virtual CTreeNode *CreateElement();
};
//---
CMyTree MyTree;
//+------------------------------------------------------------------+
//| 새 트리 노드의 생성. |
//| INPUT: 없음. |
//| OUTPUT: 새 트리 노드에 대한 포인터 또는 NULL. |
//| 비고: 없음. |
//+------------------------------------------------------------------+
CTreeNode *CMyTree::CreateElement()
{
CMyTreeNode *node=new CMyTreeNode;
//---
return(node);
}
//+------------------------------------------------------------------+
//| m_long 값을 사용하여 목록에서 요소 검색. |
//| INPUT: find_long - 검색된 값. |
//| OUTPUT: 찾은 목록 요소의 포인터, 또는 NULL. |
//| 비고: 없음. |
//+------------------------------------------------------------------+
CMyTreeNode* CMyTree::FindByLong(long find_long)
{
CMyTreeNode *res=NULL;
CMyTreeNode *node;
//--- 검색 매개 변수를 전달하기 위한 트리 노드 생성
node=new CMyTreeNode;
if(node==NULL) return(NULL);
node.SetLong(find_long);
//---
res=Find(node);
delete node;
//---
return(res);
}
//+------------------------------------------------------------------+
//| script "testing of class CMyTree" |
//+------------------------------------------------------------------+
//--- 문자열 초기화를 위한 배열
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; //--- 클래스 CMyTreeNode 샘플에 대한 임시 포인터
//---
printf("Start test %s.",__FILE__);
//--- extCountedNodes의 양으로 MyTreeNode 클래스의 인스턴스를 채웁니다.
beg_time=GetTickCount();
for(i=0;i<extCountedNodes;i++)
{
node=MyTree.CreateElement();
if(node==NULL)
{
//--- 비상구
printf("%s (%4d): create error",__FILE__,__LINE__);
return(__LINE__);
}
NodeSetData(node,i);
node.SetLong(i);
MyTree.Insert(node);
}
end_time=GetTickCount();
printf("MyTree 채우기 시간은 %d ms.",end_time-beg_time);
//--- 임시 트리 TmpMyTree 생성.
CMyTree TmpMyTree;
//--- 트리 요소의 50% 분리(모두 짝수)
//--- 임시 트리 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("MyTree %d 요소 삭제시간은 %d ms.",extCountedNodes/2,end_time-beg_time);
//--- 분리 반환
node=TmpMyTree.Root();
while(node!=NULL)
{
if(TmpMyTree.Detach(node)) MyTree.Insert(node);
node=TmpMyTree.Root();
}
//--- 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))
{
//--- 파일에 쓰는 중 오류 발생
//--- 비상구
printf("%s: Error %d in %d!",__FILE__,GetLastError(),__LINE__);
//--- 떠나기 전에 파일을 닫으세요!!!
FileClose(file_handle);
return(__LINE__);
}
FileClose(file_handle);
}
//--- Load(int file_handle) 메서드의 작업 확인;
file_handle=FileOpen("MyTree.bin",FILE_READ|FILE_BIN|FILE_ANSI);
if(file_handle>=0)
{
if(!TmpMyTree.Load(file_handle))
{
//--- 파일에서 읽는 중 오류 발생
//--- 비상구
printf("%s: Error %d in %d!",__FILE__,GetLastError(),__LINE__);
//--- 떠나기 전에 파일을 닫으세요!!!
FileClose(file_handle);
return(__LINE__);
}
FileClose(file_handle);
}
//---
MyTree.Clear();
TmpMyTree.Clear();
//---
printf("테스트 종료 %s. OK!",__FILE__);
//---
return(0);
}
//+------------------------------------------------------------------+
//| 노드 내용을 저널로 출력하는 함수 |
//+------------------------------------------------------------------+
void NodeToLog(CMyTreeNode *node)
{
printf(" %I64d,%f,'%s','%s'",
node.GetLong(),node.GetDouble(),
node.GetString(),TimeToString(node.GetDateTime()));
}
//+------------------------------------------------------------------+
//| 노드를 임의 값으로 채우는 함수 |
//+------------------------------------------------------------------+
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);
}
|