接下来是数据结构中哈希表的总结,哈希表在我以前学python的时候,也被称为散列表。简单的理解来说,哈希表我们翻越的拼音字典,一个拼音对应一个汉字或多个汉字。
哈希表基础
哈希表(Hash Table):也叫做散列表。是根据关键码值(Key Value)直接进行访问的数据结构。也就是说,它通过键
key
和一个映射函数Hash(key)
计算出对应的值value
,把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做「哈希函数(散列函数)」,存放记录的数组叫做「哈希表(散列表)」。
具体可以参考下面两篇文章,分别采用python和C++实现
01.哈希表知识 | 算法通关手册 (itcharge.cn)
这里借用上面资料对哈希表进行一个总结
- 哈希表:通过键
key
和一个映射函数Hash(key)
计算出对应的值value
,把关键码值映射到表中一个位置来访问记录,以加快查找的速度。 - 哈希函数:将哈希表中元素的关键键值映射为元素存储位置的函数。
- 哈希冲突:不同的关键字通过同一个哈希函数可能得到同一哈希地址。
掌握哈希函数,哈希冲突这两个关键的问题,而对于字符串,浮点型等数据也会先转成整形,在通过哈希函数映射。
哈希函数:直接定址法、除留余数法、平方取中法、基数转换法、数字分析法、折叠法、随机数法、乘积法、点积法等。
哈希冲突:开放地址法和链地址法。
下面是STL中的字典结构
映射 | 底层实现 | 是否有序 | 数值是否可以重复 | 能否更改数值 | 查询效率 | 增删效率 |
---|---|---|---|---|---|---|
std::map | 红黑树 | key有序 | key不可重复 | key不可修改 | O(logn) | O(logn) |
std::multimap | 红黑树 | key有序 | key可重复 | key不可修改 | O(log n) | O(log n) |
std::unordered_map | 哈希表 | key无序 | key不可重复 | key不可修改 | O(1) | O(1) |
C++中STL的哈希表解决哈希冲突采用的链式地址法。
当然这里有一个问题,那就是采用链式地址法的时候,如果每次插入的key所对应的映射值都是同一个,那么最后的结果就是哈希表被退化成了链表,查询效率为O(n)。虽然也有办法解决,那就是扩容因子,比如当你不同key对应同一个值的value时,后面链表长度超过8个,我就给整个空间扩容。不过这样的效果不一定理想,还可以把哈希链表改成红黑树,这样查询速度最低也是O(logn)了。