C++进阶哈希表

Posted Huang_ZhenSheng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++进阶哈希表相关的知识,希望对你有一定的参考价值。

1.unordered系列关联式容器

unordered_map和unordered_set 的功能和map和set是一样的,区别在于其遍历出来不是有序的,同时他们的迭代器是单向迭代器,同时效率更高!

2.底层结构

直接定址法:

取关键字的某个线性函数为散列地址:Hash(Key)= A*Key + B 优点:简单、均匀 缺点:需要事先知道关键字的分布情况 使用场景:适合查找比较小且连续的情况

除留余数法:

设散列表中允许的地址数为m,取一个不大于m,但最接近或者等于m的质数p作为除数,按照哈希函数:Hash(key) = key% p(p<=m),将关键码转换成哈希地址

===》导致的问题:哈希冲突

不同的位置映射

不同关键字通过相同哈希哈数计算出相同的哈希地址,该种现象称为哈希冲突或哈希碰撞。

哈希冲突解决

闭散列:

哈希函数设置为:hash(key) = key % capacity; capacity为存储元素底层空间总的大小

向集合中插入元素44,会发生哈希冲突或哈希碰撞

闭散列:也叫开放定址法,当发生哈希冲突时,如果哈希表未被装满,说明在哈希表中必然还有空位置,那么可以把key存放到冲突位置中的“下一个” 空位置中去。

那如何寻找下一个空位置呢?

===》线性探测:index+i  (i = 1,2,3,4)

线性探测:从发生冲突的位置开始,依次向后探测,直到寻找到下一个空位置为止 

一旦发生哈希冲突,所有的冲突连在一起,容易产生数据“堆积”,即:不同关键码占据
了可利用的空位置,使得寻找某关键码的位置需要许多次比较,导致搜索效率降低。

如何缓解呢?

===》二次探测:index+i^2  (i = 1,2,3,4)

删除:

采用闭散列处理哈希冲突时,不能随便物理删除哈希表中已有的元素,若直接删除元素会影响其他元素的搜索。比如删除元素4,如果直接删除掉,44查找起来可能会受影响。因此线性探测采用标记的伪删除法来删除一个元素。

解决方案:每个位置存储值的同时再存储一个状态标记:空,满,删除

(闭散列)哈希表的相关代码:哈希表

以上是关于C++进阶哈希表的主要内容,如果未能解决你的问题,请参考以下文章

Hash冲突的解决方法

C++数据结构——哈希表

C++数据结构——哈希表

C++数据结构——哈希表

开放定址法构造哈希表

C++数据结构——哈希表