64,281
社区成员
发帖
与我相关
我的任务
分享
#ifndef __MYMAP_H__
#define __MYMAP_H__
#include <windows.h>
struct CPlex
{
CPlex* pNext;
void *data(){return this+1;}
static CPlex* Create(CPlex*& pHead,UINT nMax,UINT cbElement);;
void FreeDataChain();
};
class CMapPtrToPtr
{
protected:
struct CAssoc
{
CAssoc* pNext;
void* key;
void* value;
};
public:
CMapPtrToPtr(int nBlockSize=10);
int GetCount()const;
BOOL IsEmpty()const;
BOOL Lookup(void* key,void*& rValue);
void*& operator[](void* key);
void SetAt(void* key,void *newValue);
BOOL RemoveKey(void* key);
void RemoveAll();
UINT GetHashTableSize()const;
void InitHashTable(UINT nHashSize,BOOL bAllocNow=TRUE);
UINT HashKey(void* key)const;
protected:
CAssoc** m_pHashTable;
int m_nHashTableSize;
struct CPlex* m_pBlocks;
int m_nBlockSize;
CAssoc* m_pFreeList;
int m_nCount;
CAssoc* NewAssoc();
void FreeAssoc(CAssoc* pAssoc);
CAssoc* GetAssocAt(void* key,UINT& nHash)const;
public:
~CMapPtrToPtr();
};
inline UINT CMapPtrToPtr::HashKey(void* key)const
{
return ((UINT)(void*)(DWORD)key)>>4;
}
inline int CMapPtrToPtr::GetCount()const
{
return m_nCount;
}
inline BOOL CMapPtrToPtr::IsEmpty()const
{
return m_nCount==0;
}
inline void CMapPtrToPtr::SetAt(void* key,void* newValue)
{
(*this)[key]=newValue;
}
inline UINT CMapPtrToPtr::GetHashTableSize()const
{
return m_nHashTableSize;
}
#endif
#include "mymap.h"
CPlex* CPlex::Create(CPlex*& pHead,UINT nMax,UINT cbElement)
{
CPlex* p=(CPlex *)new BYTE[sizeof(CPlex)+nMax*cbElement];
p->pNext=pHead;
pHead=p;
return p;
}
void CPlex::FreeDataChain()
{
CPlex *p=this;
while(p!=NULL)
{
BYTE* pBytes=(BYTE*) p;
CPlex* pNext=p->pNext;
delete[]pBytes;
p=pNext;
}
}
CMapPtrToPtr::CAssoc* CMapPtrToPtr::NewAssoc()
{
if(m_pFreeList==NULL)
{
CPlex* newBlock=CPlex::Create(m_pBlocks,m_nBlockSize,sizeof(CAssoc));
CAssoc* pAssoc=(CAssoc*)newBlock->data();
pAssoc+=m_nBlockSize-1;
for(int i=m_nBlockSize-1;i>=0;i--,pAssoc--)
{
pAssoc->pNext=m_pFreeList;
m_pFreeList=pAssoc;
}
}
CAssoc* pAssoc=m_pFreeList;
m_pFreeList=m_pFreeList->pNext;
m_nCount++;
pAssoc->key=0;
pAssoc->value=0;
return pAssoc;
}
void CMapPtrToPtr::FreeAssoc(CAssoc* pAssoc)
{
pAssoc->pNext=m_pFreeList;
m_pFreeList=pAssoc;
m_nCount--;
if(m_nCount==0)
RemoveAll();
}
void CMapPtrToPtr::InitHashTable(UINT nHashSize,BOOL bAllocNow)
{
if(m_pHashTable!=NULL)
{
delete[]m_pHashTable;
m_pHashTable=NULL;
}
if(bAllocNow)
{
m_pHashTable=new CAssoc*[nHashSize];
memset(m_pHashTable,0,sizeof(CAssoc*)*nHashSize);
}
m_nHashTableSize=nHashSize;
}
CMapPtrToPtr::CAssoc* CMapPtrToPtr::GetAssocAt(void* key,UINT& nHash)const
{
nHash=HashKey(key)%m_nHashTableSize;
if(m_pHashTable==NULL)
return NULL;
CAssoc* pAssoc;
for(pAssoc=m_pHashTable[nHash];pAssoc!=NULL;pAssoc=pAssoc->pNext)
{
if(pAssoc->key==key)
return pAssoc;
}
return NULL;
}
BOOL CMapPtrToPtr::Lookup(void* key,void*& rValue)
{
UINT nHash;
CAssoc* pAssoc=GetAssocAt(key,nHash);
if(pAssoc==NULL)
return FALSE;
rValue=pAssoc->value;
return TRUE;
}
void*& CMapPtrToPtr::operator [](void* key)
{
UINT nHash;
CAssoc *pAssoc;
if((pAssoc=GetAssocAt(key,nHash))==NULL)
{
if(m_pHashTable==NULL)
InitHashTable(m_nHashTableSize);
pAssoc=NewAssoc();
pAssoc->key=key;
pAssoc->pNext=m_pHashTable[nHash];
m_pHashTable[nHash]=pAssoc;
}
return pAssoc->value;
}
BOOL CMapPtrToPtr::RemoveKey(void* key)
{
if(m_pHashTable==NULL)
return FALSE;
CAssoc** ppAssocPre;
ppAssocPre=&m_pHashTable[HashKey(key)%m_nHashTableSize];
CAssoc* pAssoc;
for(pAssoc=*ppAssocPre;pAssoc!=NULL;pAssoc=pAssoc->pNext)
{
if(pAssoc->key==key)
{
*ppAssocPre=pAssoc->pNext;
FreeAssoc(pAssoc);
return TRUE;
}
ppAssocPre=&pAssoc->pNext;
}
return FALSE;
}
CMapPtrToPtr::CMapPtrToPtr(int nBlockSize)
{
m_pHashTable=NULL;
m_nHashTableSize=17;
m_pBlocks=NULL;
m_nBlockSize=nBlockSize;
m_pFreeList=NULL;
m_nCount=0;
}
CMapPtrToPtr::~CMapPtrToPtr()
{
RemoveAll();
}
void CMapPtrToPtr::RemoveAll()
{
if(m_pHashTable!=NULL)
{
delete[]m_pHashTable;
m_pHashTable=NULL;
}
m_nCount=0;
m_pFreeList=NULL;
m_pBlocks->FreeDataChain();
m_pBlocks=NULL;
}
#include <iostream>
#include "mymap.cpp"
using namespace std;
int main(void)
{
CMapPtrToPtr map;
char szDay[][16]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
char week[][16]={"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
for(int i=0;i<7;++i)
map[szDay[i]]=week[i];
for(int i=0;i<7;i++)
cout<<szDay[i]<<" : "<<(char*)map[szDay[i]]<<endl;
system("pause");
return 0;
}