#ifndef __TREE_H #define __TREE_H ////////////////////////////////////////////////////////////////////////////// // Tree: template class to build a binary tree of elements of class T template class Tree { public: template class Node { public: Node* _Next; public: Node() : _Left(0), _Right(0) {} int _Index; T _Element; Node* _Left; Node* _Right; }; public: Tree(); ~Tree(); void Clear(); int Find(T& element); int Find(Node* _node,T& _vtx); int Add(T& element); int Add(Node* _node,T& _vtx,int _index); // total nodes currently in tree int Entries() { return _Size; } void Reserve(int count) { _AllocatedNodes.reserve(count); } T& operator[](int index) { return _AllocatedNodes[index]->_Element; } private: // the root node of the tree Node* _Root; // all allocated nodes in tree std::vector*> _AllocatedNodes; // size of tree int _Size; // the comparison function used to compare two elements in the tree Cmp _Cmp; }; //*************************************************************************** // Default Tree constructor - create tree with no allocated nodes //*************************************************************************** template Tree::Tree() { _Root=0; _Size=0; } //*************************************************************************** // Tree destructor //*************************************************************************** template Tree::~Tree() { Clear(); } template void Tree::Clear() { for (int i=0;i<_AllocatedNodes.Entries();i++) { _NodePile.Release(_AllocatedNodes[i]); } _AllocatedNodes.SetSize(0); _Root=0; _Size=0; } //*************************************************************************** // Add : insert an element into the tree; return the index of the treenode // at which the element was added, or, if an identical element was already // in the tree, return it's index //*************************************************************************** template int Tree::Add(T& element) { if (_Root) { int index=Add(_Root,element,_Size); if (index==_Size) { // element added to tree _Size++; } else { // element not added } return index; } else { _Root=_NodePile.Allocate(); _AllocatedNodes.Add(_Root); _Root->_Element=element; _Root->_Index=0; _Root->_Left=0; _Root->_Right=0; _Size++; return 0; } } //*************************************************************************** // Add : insert an element into the given node; return the index of the // treenode at which the element was added, or, if an identical element was // already in the tree, return it's index //*************************************************************************** template int Tree::Add(Node* _node,T& element,int _index) { // compare given element with element at given node int cmp=_Cmp.compare(_node->_Element,element); if (cmp==0) { // identical - return index of this node return _node->_Index; } else { if (cmp==-1) { // this node less than new node if (_node->_Left) { // send down left tree return Add(_node->_Left,element,_index); } else { // no left node - create one _node->_Left=_NodePile.Allocate(); _AllocatedNodes.Add(_node->_Left); _node->_Left->_Element=element; _node->_Left->_Index=_index; _node->_Left->_Left=0; _node->_Left->_Right=0; return _index; } } else { // this node greater than new node if (_node->_Right) { // send down right tree return Add(_node->_Right,element,_index); } else { // no right node - create one _node->_Right=_NodePile.Allocate(); _AllocatedNodes.Add(_node->_Right); _node->_Right->_Element=element; _node->_Right->_Index=_index; _node->_Right->_Left=0; _node->_Right->_Right=0; return _index; } } } } //*************************************************************************** // Find: try and find a matching element in the tree; return the index of the // treenode at which a match was found, or -1 if no match found //*************************************************************************** template int Tree::Find(T& element) { return _Root ? Find(_Root,element) : -1; } //*************************************************************************** // Find: try and find a matching element in the given node; return the index // of the treenode at which a match was found, or -1 if no match found //*************************************************************************** template int Tree::Find(Node* _node,T& element) { // compare given element with element at given node int cmp=_Cmp.compare(_node->_Element,element); if (cmp==0) { // identical - return index of this node return _node->_Index; } else { if (cmp==-1) { // this node less than new node if (_node->_Left) { // send down left tree return Find(_node->_Left,element); } else { // no left node - no match on this subtree return -1; } } else { // this node greater than new node if (_node->_Right) { // send down right tree return Find(_node->_Right,element); } else { // no left node - no match on this subtree return -1; } } } } #endif