hash溢出表的实现原理

来源:互联网 发布:linux内核版本与时间 编辑:程序博客网 时间:2024/05/29 14:29
溢出hash表设计图[点击放大]
溢出hash表设计图 来源:朱翔

   介绍溢出哈希表的实现机理,并给出具体实现代码。溢出哈希表是在hash 表填入过程中,将冲突的元素顺序填入到溢出表中,而当查找过程中发现冲突时,就在溢出表中进行顺序查找。   溢出哈希表的设计图,具体实现如下:首先:哈希表中每个元素被称为Node,Node类必须包含两个函数:GetKey,Hash。GetKey返回每个节点Node的键值key,key值唯一标识节点Node;Hash函数用于生成Node对象Key的对应hash値,下面给出Node的具体定义:
class NodeStruct{ private: unsigned int key; public: //使用nelement计算NodeStruct对象的hash值 static inline unsigned int Hash (unsigned int nelement) { return key % modulo; } //获得NodeStruct对象的key值 inline unsigned int GetKey () { return key; }}
在overflow Hash表中查找key值对应node节点创建_table,_overflowBits,_allocBits,其中_table是保存哈希表中Node的数组,_allocBits中的第n位标识_table中的第n个Node是否已经创建,1标识_table中的第n个Node已经被创建,0标识_table中第n个Node是否overflow,_overflowBit中的第n位标识_table中的第n个Node是否发生冲突,下面是查询与创建node的具体实现:
NodeStruct * OverfolwHash::Lookup (unsigned int key) { //对掩码进行初始化 const uint32_t upperBit = 0x80000000; //计算key对应的hash值 unsigned int entry = NodeStruct::Hash(key, _numElements); //ptr为key对应Node在_table中的起始位置 NODE *ptr = &_table[entry]; NODE *ptrEnd = &_table[_numElements]; //allocPtr为key对应Node在_allocBits中的位置,因为_allocBits数组的类型是uint32_t,//所以需要对entry向右位移5位 uint32_t *allocPtr = &_allocBits[entry >> 5]; // overflowPtr为key对应Node在_ overflowBits中的位置 uint32_t *overflowPtr = &_overflowBits[entry >> 5]; uint32_t mask = upperBit >> (entry & 31); for(;;) { //如果allocPtr没有创建Node,没有占用 if((*allocPtr & mask) == 0) return NULL; //判断ptr指向节点的key值与查询的key值是否相等,如果相等, //则ptr就是查询的Nodeif(ptr->GetKey() == key) return ptr; //如果对应的溢出位为零,则hash表中没有对应key值的节点,返回; //如果对应的溢出位不为零,则标识hash表对应节点发生冲突,继续在hash表中查找key值对应节点 if((*overflowPtr & mask) == 0) return NULL; //遍历到_table的最末节点ptrEnd,则重新从_table的头部开始查找 if((++ptr) == ptrEnd) { entry = 0; ptr = _table; allocPtr = _allocBits; overflowPtr = _overflowBits; mask = upperBit; } else { mask >>= 1; if(mask == 0) { allocPtr++; overflowPtr++; mask = upperBit; } } } }
 
0 0
原创粉丝点击