N
Nobody
This is sort of my first attempt at writing a template container class, just
wanted some feedback if everything looks kosher or if there can be any
improvements. This is a template class for a binary search tree. Note there
is a requirement for this to be a Win32/MFC "friendly" class, thus the use
of CObject and POSITION. There is also a requirement for there not to be a
separate iterator class.
template <class TYPE, class ARG_TYPE = const TYPE&> class CBinarySearchTree;
template <class TYPE, class ARG_TYPE>
class CBinarySearchTree : public CObject
{
// Constructors
public:
CBinarySearchTree();
// Attributes
public:
int GetCount() const;
POSITION GetRoot() const;
POSITION GetLeft(POSITION& pos) const;
POSITION GetRight(POSITION& pos) const;
ARG_TYPE GetElement(POSITION& pos) const;
// Operations
public:
BOOL Insert(ARG_TYPE newElement);
BOOL Remove(ARG_TYPE element);
void RemoveAll();
POSITION Find(ARG_TYPE element);
// Implementation
public:
virtual ~CBinarySearchTree();
protected:
struct _TREENODE
{
TYPE element;
_TREENODE* pLeft;
_TREENODE* pRight;
};
protected:
_TREENODE* m_pRoot;
UINT m_nCount;
protected:
BOOL Insert(ARG_TYPE newElement, _TREENODE*& pNode);
BOOL Remove(ARG_TYPE element, _TREENODE*& pNode);
LPVOID FindMin(_TREENODE* pNode);
};
////////////////////////////////////////////////////////////////////////////
/
template <class TYPE, class ARG_TYPE>
CBinarySearchTree<TYPE, ARG_TYPE>::CBinarySearchTree()
{
m_pRoot = NULL;
m_nCount = 0;
}
template <class TYPE, class ARG_TYPE>
CBinarySearchTree<TYPE, ARG_TYPE>::~CBinarySearchTree()
{
RemoveAll();
}
template <class TYPE, class ARG_TYPE>
int CBinarySearchTree<TYPE, ARG_TYPE>::GetCount() const
{
return m_nCount;
}
template <class TYPE, class ARG_TYPE>
POSITION CBinarySearchTree<TYPE, ARG_TYPE>::GetRoot() const
{
return (POSITION)m_pRoot;
}
template <class TYPE, class ARG_TYPE>
POSITION CBinarySearchTree<TYPE, ARG_TYPE>::GetLeft(POSITION& pos) const
{
return (POSITION)(((_TREENODE*)pos)->pLeft);
}
template <class TYPE, class ARG_TYPE>
POSITION CBinarySearchTree<TYPE, ARG_TYPE>::GetRight(POSITION& pos) const
{
return (POSITION)(((_TREENODE*)pos)->pRight);
}
template <class TYPE, class ARG_TYPE>
ARG_TYPE CBinarySearchTree<TYPE, ARG_TYPE>::GetElement(POSITION& pos) const
{
return ((_TREENODE*)pos)->element;
}
template <class TYPE, class ARG_TYPE>
BOOL CBinarySearchTree<TYPE, ARG_TYPE>::Insert(ARG_TYPE newElement)
{
return Insert(newElement, m_pRoot);
}
template <class TYPE, class ARG_TYPE>
BOOL CBinarySearchTree<TYPE, ARG_TYPE>::Remove(ARG_TYPE element)
{
return Remove(element, m_pRoot);
}
template <class TYPE, class ARG_TYPE>
void CBinarySearchTree<TYPE, ARG_TYPE>::RemoveAll()
{
while (m_pRoot != NULL)
Remove(m_pRoot->element);
}
template <class TYPE, class ARG_TYPE>
POSITION CBinarySearchTree<TYPE, ARG_TYPE>::Find(ARG_TYPE element)
{
return NULL;
}
template <class TYPE, class ARG_TYPE>
BOOL CBinarySearchTree<TYPE, ARG_TYPE>::Insert(ARG_TYPE newElement,
_TREENODE*& pNode)
{
if (pNode != NULL)
{
if (newElement < pNode->element)
return Insert(newElement, pNode->pLeft);
if (newElement > pNode->element)
return Insert(newElement, pNode->pRight);
}
else
{
pNode = new _TREENODE;
if (!pNode)
return FALSE;
m_nCount++;
pNode->element = newElement;
pNode->pLeft = NULL;
pNode->pRight = NULL;
return TRUE;
}
return TRUE;
}
template <class TYPE, class ARG_TYPE>
BOOL CBinarySearchTree<TYPE, ARG_TYPE>::Remove(ARG_TYPE element, _TREENODE*&
pNode)
{
_TREENODE* pTempNode = NULL;
if (!pNode)
return TRUE;
if (element < pNode->element)
{
Remove(element, pNode->pLeft);
}
else if (element > pNode->element)
{
Remove(element, pNode->pRight);
}
else if (pNode->pLeft != NULL && pNode->pRight != NULL)
{
pTempNode = (_TREENODE*)FindMin(pNode->pRight);
pNode->element = pTempNode->element;
Remove(element, pNode->pRight);
}
else
{
pTempNode = pNode;
if (m_nCount > 0)
m_nCount--;
if (!pNode->pLeft)
pNode = pNode->pRight;
else if (!pNode->pRight)
pNode = pNode->pLeft;
delete pTempNode;
}
return TRUE;
}
template <class TYPE, class ARG_TYPE>
LPVOID CBinarySearchTree<TYPE, ARG_TYPE>::FindMin(_TREENODE* pNode)
{
if (!pNode)
return NULL;
else if (!pNode->pLeft)
return (LPVOID)pNode;
return FindMin(pNode->pLeft);
}
Thanks!
wanted some feedback if everything looks kosher or if there can be any
improvements. This is a template class for a binary search tree. Note there
is a requirement for this to be a Win32/MFC "friendly" class, thus the use
of CObject and POSITION. There is also a requirement for there not to be a
separate iterator class.
template <class TYPE, class ARG_TYPE = const TYPE&> class CBinarySearchTree;
template <class TYPE, class ARG_TYPE>
class CBinarySearchTree : public CObject
{
// Constructors
public:
CBinarySearchTree();
// Attributes
public:
int GetCount() const;
POSITION GetRoot() const;
POSITION GetLeft(POSITION& pos) const;
POSITION GetRight(POSITION& pos) const;
ARG_TYPE GetElement(POSITION& pos) const;
// Operations
public:
BOOL Insert(ARG_TYPE newElement);
BOOL Remove(ARG_TYPE element);
void RemoveAll();
POSITION Find(ARG_TYPE element);
// Implementation
public:
virtual ~CBinarySearchTree();
protected:
struct _TREENODE
{
TYPE element;
_TREENODE* pLeft;
_TREENODE* pRight;
};
protected:
_TREENODE* m_pRoot;
UINT m_nCount;
protected:
BOOL Insert(ARG_TYPE newElement, _TREENODE*& pNode);
BOOL Remove(ARG_TYPE element, _TREENODE*& pNode);
LPVOID FindMin(_TREENODE* pNode);
};
////////////////////////////////////////////////////////////////////////////
/
template <class TYPE, class ARG_TYPE>
CBinarySearchTree<TYPE, ARG_TYPE>::CBinarySearchTree()
{
m_pRoot = NULL;
m_nCount = 0;
}
template <class TYPE, class ARG_TYPE>
CBinarySearchTree<TYPE, ARG_TYPE>::~CBinarySearchTree()
{
RemoveAll();
}
template <class TYPE, class ARG_TYPE>
int CBinarySearchTree<TYPE, ARG_TYPE>::GetCount() const
{
return m_nCount;
}
template <class TYPE, class ARG_TYPE>
POSITION CBinarySearchTree<TYPE, ARG_TYPE>::GetRoot() const
{
return (POSITION)m_pRoot;
}
template <class TYPE, class ARG_TYPE>
POSITION CBinarySearchTree<TYPE, ARG_TYPE>::GetLeft(POSITION& pos) const
{
return (POSITION)(((_TREENODE*)pos)->pLeft);
}
template <class TYPE, class ARG_TYPE>
POSITION CBinarySearchTree<TYPE, ARG_TYPE>::GetRight(POSITION& pos) const
{
return (POSITION)(((_TREENODE*)pos)->pRight);
}
template <class TYPE, class ARG_TYPE>
ARG_TYPE CBinarySearchTree<TYPE, ARG_TYPE>::GetElement(POSITION& pos) const
{
return ((_TREENODE*)pos)->element;
}
template <class TYPE, class ARG_TYPE>
BOOL CBinarySearchTree<TYPE, ARG_TYPE>::Insert(ARG_TYPE newElement)
{
return Insert(newElement, m_pRoot);
}
template <class TYPE, class ARG_TYPE>
BOOL CBinarySearchTree<TYPE, ARG_TYPE>::Remove(ARG_TYPE element)
{
return Remove(element, m_pRoot);
}
template <class TYPE, class ARG_TYPE>
void CBinarySearchTree<TYPE, ARG_TYPE>::RemoveAll()
{
while (m_pRoot != NULL)
Remove(m_pRoot->element);
}
template <class TYPE, class ARG_TYPE>
POSITION CBinarySearchTree<TYPE, ARG_TYPE>::Find(ARG_TYPE element)
{
return NULL;
}
template <class TYPE, class ARG_TYPE>
BOOL CBinarySearchTree<TYPE, ARG_TYPE>::Insert(ARG_TYPE newElement,
_TREENODE*& pNode)
{
if (pNode != NULL)
{
if (newElement < pNode->element)
return Insert(newElement, pNode->pLeft);
if (newElement > pNode->element)
return Insert(newElement, pNode->pRight);
}
else
{
pNode = new _TREENODE;
if (!pNode)
return FALSE;
m_nCount++;
pNode->element = newElement;
pNode->pLeft = NULL;
pNode->pRight = NULL;
return TRUE;
}
return TRUE;
}
template <class TYPE, class ARG_TYPE>
BOOL CBinarySearchTree<TYPE, ARG_TYPE>::Remove(ARG_TYPE element, _TREENODE*&
pNode)
{
_TREENODE* pTempNode = NULL;
if (!pNode)
return TRUE;
if (element < pNode->element)
{
Remove(element, pNode->pLeft);
}
else if (element > pNode->element)
{
Remove(element, pNode->pRight);
}
else if (pNode->pLeft != NULL && pNode->pRight != NULL)
{
pTempNode = (_TREENODE*)FindMin(pNode->pRight);
pNode->element = pTempNode->element;
Remove(element, pNode->pRight);
}
else
{
pTempNode = pNode;
if (m_nCount > 0)
m_nCount--;
if (!pNode->pLeft)
pNode = pNode->pRight;
else if (!pNode->pRight)
pNode = pNode->pLeft;
delete pTempNode;
}
return TRUE;
}
template <class TYPE, class ARG_TYPE>
LPVOID CBinarySearchTree<TYPE, ARG_TYPE>::FindMin(_TREENODE* pNode)
{
if (!pNode)
return NULL;
else if (!pNode->pLeft)
return (LPVOID)pNode;
return FindMin(pNode->pLeft);
}
Thanks!