CMap分析
来源:互联网 发布:移动工作站 知乎 编辑:程序博客网 时间:2024/05/07 21:09
1.CMap定义
template< class KEY, class ARG_KEY, class VALUE, class ARG_VALUE >class CMap : public CObject
参数说明
KEY
key的类型。其类型可以是用户自定义的类
ARG _ KEY
KEY的数据类型。通常是KEY的引用
VALUE
值类型。可以是用户自定义的类
ARG _ VALUE
VALUE的数据类型。通过是VALUE的引用。
2.CMap数据结构
CMap数据结构见下图
数据类型及CMap数据成员
// CPairstruct CPair{const KEY key; //Key是类型VALUE value;protected://ARG_KEY 是Key的值类型 若Key是CString 则AGR_KEY可以是const char *//ARG_KEY指定的key作为哈希函数的参数CPair( ARG_KEY keyval ) : key( keyval ){}}//CAssoc 链表节点class CAssoc : public CPair{friend class CMap<KEY,ARG_KEY,VALUE,ARG_VALUE>;CAssoc* pNext; //指向下一个链表节点UINT nHashValue; //哈希值 // needed for efficient iterationpublic:CAssoc( ARG_KEY key ) : CPair( key ) {}};如果hash地址冲突,则插入的元素保存在pNext中。
CAssoc** m_pHashTable; //以链表节点代指哈希名 m_pHashTable为CAssoc指针一维数组
UINT m_nHashTableSize; //哈希表容量
INT_PTR m_nCount; //哈希表中元素个数
3.初始化
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>void CMap<KEY, ARG_KEY, VALUE, ARG_VALUE>::InitHashTable(UINT nHashSize, BOOL bAllocNow){//......//......if (bAllocNow){m_pHashTable = new CAssoc* [nHashSize]; //nHashSize哈希表容器大小ENSURE(m_pHashTable != NULL);memset(m_pHashTable, 0, sizeof(CAssoc*) * nHashSize); //hash表初始化为0}m_nHashTableSize = nHashSize;}
4.哈希函数
ARG_KEY用于计算哈希地址
template<class ARG_KEY>AFX_INLINE UINT AFXAPI HashKey(ARG_KEY key){// default identity hash - works for most primitive valuesreturn (DWORD)(((DWORD_PTR)key)>>4);}template<> UINT AFXAPI HashKey<LPCWSTR> (LPCWSTR key);template<> UINT AFXAPI HashKey<LPCSTR> (LPCSTR key);template<> UINT AFXAPI HashKey<LPCWSTR> (LPCWSTR key){ENSURE_ARG(AfxIsValidString(key));UINT nHash = 0;while (*key)nHash = (nHash<<5) + nHash + *key++;return nHash;}template<> UINT AFXAPI HashKey<LPCSTR> (LPCSTR key){ENSURE_ARG(AfxIsValidString(key));UINT nHash = 0;while (*key)nHash = (nHash<<5) + nHash + *key++;return nHash;}如果Key为用户自定义类类型,则必须要提供Hask函数。
5.插入一个元素
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>VALUE& CMap<KEY, ARG_KEY, VALUE, ARG_VALUE>::operator[](ARG_KEY key){ASSERT_VALID(this);UINT nHashBucket, nHashValue;CAssoc* pAssoc;//GetAssocAt 找出key对应的CAssoc节点//key传入变量//nHashBucket为传出变量。它为key对应的桶号 即pHashTable数组的索引//nHashValue为传出变量。它为key对应的值 if ((pAssoc = GetAssocAt(key, nHashBucket, nHashValue)) == NULL){//......// it doesn't exist, add a new AssociationpAssoc = NewAssoc(key);//保存计算得到的哈希值pAssoc->nHashValue = nHashValue;//'pAssoc->value' is a constructed object, nothing more// put into hash tablepAssoc->pNext = m_pHashTable[nHashBucket];m_pHashTable[nHashBucket] = pAssoc; //创}//注意,返回的是值的引用。这样可以方便修改key对应的值//如果value的类型为CPoint 则map[1]=CPoint(562,963);//即pAssoc->value=CPoint(562,963);return pAssoc->value; // return new reference}template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>typename CMap<KEY, ARG_KEY, VALUE, ARG_VALUE>::CAssoc*CMap<KEY, ARG_KEY, VALUE, ARG_VALUE>::GetAssocAt(ARG_KEY key, UINT& nHashBucket, UINT& nHashValue) const// find association (or return NULL){nHashValue = HashKey<ARG_KEY>(key); //计算出哈希值nHashBucket = nHashValue % m_nHashTableSize; //计算出桶号if (m_pHashTable == NULL)return NULL;// see if it existsCAssoc* pAssoc;for (pAssoc = m_pHashTable[nHashBucket]; pAssoc != NULL; pAssoc = pAssoc->pNext){//CompareElements比较键值 处理hash地址冲突 if (pAssoc->nHashValue == nHashValue && CompareElements(&pAssoc->key, &key))return pAssoc;}return NULL;}
6.查找函数
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>BOOL CMap<KEY, ARG_KEY, VALUE, ARG_VALUE>::Lookup(ARG_KEY key, VALUE& rValue) const{ASSERT_VALID(this);UINT nHashBucket, nHashValue;CAssoc* pAssoc = GetAssocAt(key, nHashBucket, nHashValue);if (pAssoc == NULL)return FALSE; // not in maprValue = pAssoc->value;return TRUE;}
7.实例
#include "stdafx.h" void TestCMap1() { CMap<int,int,CPoint,CPoint> myMap; int i; myMap.InitHashTable( 257 ); // Add 10 elements to the map. for (i=0;i < 200;i++) myMap[i] = CPoint(i, i); // Remove the elements with even key values. CPoint pt; for (i=0; myMap.Lookup( i, pt ) ;i+=2) { myMap.RemoveKey( i ); }#ifdef _DEBUG ASSERT(myMap.GetCount() == 100); afxDump.SetDepth( 1 ); afxDump << "myMap: " << &myMap << "\n";#endif } void TestCMap2() {CMap<CString, LPCTSTR, CString, LPCTSTR> itemMap;itemMap.InitHashTable(120);itemMap[L"vk"]=L"vi kong"; }
- CMap分析
- CMap
- CMap
- cmap
- CMap
- CMap
- CMAP
- CMap 用法
- CMap使用
- CMap有关
- CMap类
- CMap 语录
- CMap详解
- CMap详解
- cmap 表
- CMap map
- CMap源代码
- cmap 表
- js+css页签
- linux下 更新 java版本
- php 常用文件操作函数
- 基于SSL实现MySQL的加密主从复制
- js 无缝滚动
- CMap分析
- Android 基于sx8652的触摸屏驱动(gpio模拟spi)
- Unable to load bean: type:com.opensymphony.xwork2.ObjectFactory class:org.apache.struts2.spring.Stru
- Same Tree
- 处理方法 "gist_geometry_ops" 的操作符类 "gist" 不存在
- 小米Android4.0系统网络问题解决
- JS+CSS简单实现DIV遮罩层显示隐藏
- android手势操作滑动效果触摸屏事件处理、GestureDetector用法
- $.ajax在谷歌浏览器传入中文乱码的情况