#pragma once
template<typename KEY, typename VALUE, typename ARG_KEY = KEY&, typename ARG_VALUE = VALUE&>
class CMap
{
struct SNode
{
KEY key;
VALUE value;
SNode *pLeft, *pRight;
};
SNode *m_pRoot;
int m_nSize;
public:
typedef SNode * POSTION;
void SetAt(KEY key, ARG_VALUE value);
bool Lookup(KEY key, ARG_VALUE rValue) const;
ARG_VALUE operator[](KEY key);
void RemoveAll();
void RemoveKey(SNode * p);
CMap();
virtual ~CMap();
int GetSize()const
{
return m_nSize;
}
void * GetRootPoint() const
{
return m_pRoot;
}
};
template<typename KEY, typename VALUE, typename ARG_KEY, typename ARG_VALUE>
void CMap<KEY, VALUE, ARG_KEY, ARG_VALUE>::SetAt(KEY key, ARG_VALUE value)
{
(*this)[key] = value;
}
template<typename KEY, typename VALUE, typename ARG_KEY, typename ARG_VALUE>
bool CMap<KEY, VALUE, ARG_KEY, ARG_VALUE>::Lookup(KEY key, ARG_VALUE rValue) const
{
SNode *p = m_pRoot;
while (p)
{
if (p->key == key)
{
rValue = p->value;
return true;
}
else if (p->key > key)
p = p->pLeft;
else
p = p->pRight;
}
return false;
}
template<typename KEY, typename VALUE, typename ARG_KEY, typename ARG_VALUE>
ARG_VALUE CMap<KEY, VALUE, ARG_KEY, ARG_VALUE>::operator[](KEY key)
{
SNode **p = &m_pRoot;
while (*p)
{
if ((*p)->key == key)
break;
else if ((*p)->key > key)
p = &((*p)->pLeft);
else
p = &((*p)->pRight);
}
if (*p)
{
return (*p)->value;
}
SNode *pNew = new SNode();
pNew->key = key;
*p = pNew;
++m_nSize;
return (*p)->value;
}
template<typename KEY, typename VALUE, typename ARG_KEY, typename ARG_VALUE>
void CMap<KEY, VALUE, ARG_KEY, ARG_VALUE>::RemoveAll()
{
if (m_pRoot)
RemoveKey(m_pRoot);
m_pRoot = nullptr;
m_nSize = 0;
}
template<typename KEY, typename VALUE, typename ARG_KEY, typename ARG_VALUE>
void CMap<KEY, VALUE, ARG_KEY, ARG_VALUE>::RemoveKey(SNode * p)
{
if (p->pLeft)
RemoveKey(p->pLeft);
if (p->pRight)
RemoveKey(p->pRight);
delete p;
}
template<typename KEY, typename VALUE, typename ARG_KEY, typename ARG_VALUE>
CMap<KEY, VALUE, ARG_KEY, ARG_VALUE>::CMap()
{
m_pRoot = nullptr;
m_nSize = 0;
}
template<typename KEY, typename VALUE, typename ARG_KEY, typename ARG_VALUE>
CMap<KEY, VALUE, ARG_KEY, ARG_VALUE>::~CMap()
{
RemoveAll();
}