实现map

tan625747 2010-03-29 10:07:16
实现可供操作的ADT字典(map),以dll或者代码的形式提供给我调用,要尽量优化到可以处理大量不同类型的数据而保持一定的效率


就是实现map ,网上很难找到实现map 的方法,在这里希望高人,能提高实现思路,或指导看什么的书,本人感激不尽。
...全文
411 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
xixiaoliu 2010-04-01
  • 打赏
  • 举报
回复
http://xlcontainers.codeplex.com/

我写的,含动态数组、双向链表、红黑书、Set、Map、String 实现
selooloo 2010-03-29
  • 打赏
  • 举报
回复
头文件

#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;
}
cy330206 2010-03-29
  • 打赏
  • 举报
回复
帮顶,,最近也在学习这个东西
SiGoYi 2010-03-29
  • 打赏
  • 举报
回复

不明白LZ为什么非要自己实现。
STL的map不是很好用吗?如果要扩功能方便使用的话,学习点Effect STL可以了。

AlanBruce 2010-03-29
  • 打赏
  • 举报
回复
UP UP
xixiaoliu 2010-03-29
  • 打赏
  • 举报
回复
首先声明偶不是高手
前阵子自己还练习写了个
思路是这样的:
1、先写个红黑树
2、然后接口改良一下
3、测试下性能是不是过得去
cattycat 2010-03-29
  • 打赏
  • 举报
回复
不知道你的map是hashmap呢还是类似stl的map?
如果是hashmap这个实现起来还算简单点。网上可以搜一下。
如果是stl的map,底层是红黑树实现的,就麻烦点了,你需要看stl源码了。
BT六眼飞鱼 2010-03-29
  • 打赏
  • 举报
回复
首先申明俺不是高手。
昨天自己还练习写了个。。
思路是这样的
1.用一个散列函数 散列一下Key
2.然后把这个key和value放到一个数组中
3.如果有冲突 则用一个链表将他们连起来
yuzl32 2010-03-29
  • 打赏
  • 举报
回复
友情Up.
  • 打赏
  • 举报
回复
拒绝0回复! 顶!
失落的凡凡 2010-03-29
  • 打赏
  • 举报
回复
看要求,似乎是要用hashmap的
praylgjywjy 2010-03-29
  • 打赏
  • 举报
回复
UP!!!
程序园苑 2010-03-29
  • 打赏
  • 举报
回复
强人啊 ,学习



[Quote=引用 9 楼 selooloo 的回复:]
头文件

C/C++ code

#ifndef __MYMAP_H__
#define __MYMAP_H__
#include <windows.h>
struct CPlex
{
CPlex* pNext;
void *data(){return this+1;}
static CPlex* Create(CPlex*&……
[/Quote]
mLee79 2010-03-29
  • 打赏
  • 举报
回复
偶自己用的: http://x4c.googlecode.com/svn/trunk/x4c/inc/x4c/algo/xrbtree.h
支持 sizeof( void* ) * 8 个索引的RB-tree, 实测性能还行, 不过是C的...
可以 svn co http://x4c.googlecode.com/svn/trunk/x4c 试试...

wade_2003 2010-03-29
  • 打赏
  • 举报
回复
楼主可以试试9楼的代码哈
才刚接触到map这个东西,不是很懂
ithiker 2010-03-29
  • 打赏
  • 举报
回复
顶,9楼很强大
cfanxue 2010-03-29
  • 打赏
  • 举报
回复
UP UP UP 对map不懂
某某9 2010-03-29
  • 打赏
  • 举报
回复
本人不懂,友情up一下
建议看stl源码剖析了
herman~~ 2010-03-29
  • 打赏
  • 举报
回复
本人不懂,友情up一下
建议看stl源码剖析了
moon6623 2010-03-29
  • 打赏
  • 举报
回复
UP UP
加载更多回复(2)

64,281

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧