这是个在暴雪字符串哈希算法基础上实现的哈希表。在代码实现上有一定优化。
设计上:
1)加密表是足够长的(unsigned long)无符号型数组。数组的值是由算法计算的固定的一些值。加密表是用来计算字符串(在某种子的情况下)的哈希值。
2)哈希值是字符串(大写)的所有的字符的ascii码相关的。使用单向散列函数,从概率上认为,不同字符串的3种不同的种子的3个哈希值不会是都是相同的。(计算的是10的22.3次方分之一的概率)
3)每个节点有3个hash值(hash1,hash2,hash3),hash1 是寻位的基准,hash2,hash3 是判断节点是否相同的标准。
4)hash1值冲突的解决方式是,从hash1开始遍历表并获取空位(顺延方式)
5)把表查找字符串键优化为比较三个整形键值(先使用折半方式,然后顺延方式查找。因为表内存不够时是会拓展一倍内存的)
6)表长度是2的次幂,最小是16。表内存不够时可以拓展一倍,由空闲位置计数器来判断
特点:
(1)插入
使用顺延方式查找空位,没有使用链表。节省内存空间。
(2)查找
因为表内存不够时是会拓展一倍内存的 。先通过hash1不断去掉高位的方式来检查能适应表内存拓展方式和哈希取余方式
2)三哈希值比较方式来检查:
比较键值是比较3个整形数,而不是字符串,可以提高查找比较效率
(3)移除查找到节点后,设置该节点的哈希值为0,并显式调用节点的值对象的析构函数
1、hash算法理论
从字符串数组中查找匹配的字符串最合适的算法自然是使用哈希表。所谓Hash,一般是一个整数,通过某种算法,可以把一个字符串"压缩" 成一个整数,这个数称为Hash,当然,无论如何,一个32位整数是无法对应回一个字符串的,但如果有合适的校验方式,两个字符串计算出的Hash值相等的可能非常小。
2)hash函数(单向散列函数)
Blizzard的哈希算法是非常高效的(代码实现可参考 章节 1-2 由加密表随机种子(bzhashstr)),使用的是单向散列函数(One-Way Hash),举个例子,字符串"unitneutralacritter.grp"通过这个算法得到的结果是0xA26067F3。
通常是构造一个数组来作为哈希表,这个数组的容量根据程序的要求来定义(如1024),每一个Hash值通过位与运算对应到数组中的一个位置,只要检查这个字符串的哈希值对的位置有没有被占用。最快的复杂度是 O(1)。