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++进阶哈希表的主要内容,如果未能解决你的问题,请参考以下文章