#pragma once
template<typename KEY, typename VALUE, typename ARG_KEY = KEY&, typename ARG_VALUE = VALUE&>
class CMap
{
struct SNode
{
KEY key;
VALUE value;
SNode *pNext;
}**m_pHash;
int m_nCount;
int m_nSize;
public:
CMap(int nCount = 17);
~CMap();
int GetHashTableSize() const
{
return m_nSize;
}
int GetSize() const
{
return m_nCount;
}
void SetAt(ARG_KEY key, ARG_VALUE newValue);
bool LookUp(ARG_KEY key, ARG_VALUE rvalue) const;
ARG_VALUE operator[](ARG_KEY key);
bool RemoveKey(ARG_KEY key);
void RemoveAll();
};
template<typename KEY, typename VALUE, typename ARG_KEY, typename ARG_VALUE>
CMap<KEY, VALUE, ARG_KEY, ARG_VALUE>::CMap(int nCount)
{
m_nSize = 0;
m_nCount = nCount;
m_pHash = new SNode *[nCount];
memset(m_pHash, ' ', sizeof(SNode *)*nCount);
}
template<typename KEY, typename VALUE, typename ARG_KEY, typename ARG_VALUE>
CMap<KEY, VALUE, ARG_KEY, ARG_VALUE>::~CMap()
{
RemoveAll();
}
template<typename KEY, typename VALUE, typename ARG_KEY, typename ARG_VALUE>
void CMap<KEY, VALUE, ARG_KEY, ARG_VALUE>::SetAt(ARG_KEY key, ARG_VALUE newValue)
{
// 调用下标号的两种方法
// operator[](key) = newValue;
(*this)[key] = newValue;
}
template<typename KEY, typename VALUE, typename ARG_KEY, typename ARG_VALUE>
bool CMap<KEY, VALUE, ARG_KEY, ARG_VALUE>::LookUp(ARG_KEY key, ARG_VALUE rvalue) const
{
int nIndex = key % m_nCount;
SNode *p = m_pHash[nIndex];
while (p)
{
if (p->key == key)
{
rvalue = p->value;
return true;
}
p = p->pNext;
}
return false;
}
template<typename KEY, typename VALUE, typename ARG_KEY, typename ARG_VALUE>
ARG_VALUE CMap<KEY, VALUE, ARG_KEY, ARG_VALUE>::operator[](ARG_KEY key)
{
++m_nSize;
int nIndex = key % m_nCount;
SNode* *p = &m_pHash[nIndex];
while (*p)
{
if ((*p)->key == key)
return (*p)->value;
p = &((*p)->pNext);
}
SNode *pNew = new SNode;
pNew->key = key;
pNew->pNext = NULL;
*p = pNew;
return pNew->value;
}
template<typename KEY, typename VALUE, typename ARG_KEY, typename ARG_VALUE>
bool CMap<KEY, VALUE, ARG_KEY, ARG_VALUE>::RemoveKey(ARG_KEY key)
{
if (m_pHash == NULL)
return false; // nothing in the table
SNode ** ppPrev = &m_pHash[key % m_nCount];
SNode* p;
for (p = *ppPrev; p != NULL; p = p->pNext)
{
if (p->key == key)
{
*ppPrev = p->pNext;
delete[]p;
return true;
}
ppPrev = &p->pNext;
}
return false; // not found
}
template<typename KEY, typename VALUE, typename ARG_KEY, typename ARG_VALUE>
void CMap<KEY, VALUE, ARG_KEY, ARG_VALUE>::RemoveAll()
{
int n = 0;
SNode **ppPrev = &m_pHash[n];
if (!m_pHash)
return;
SNode *p;
while (n < m_nCount)
{
while (p = *ppPrev)
{
*ppPrev = p->pNext;
delete[]p;
}
ppPrev = &m_pHash[++n];
}
delete[]m_pHash;
m_pHash = NULL;
m_nCount = 0;
m_nSize = 0;
}