本文重点介绍:比较和对比哈希表和 STL Map。哈希表是如何实现的?如果输入的数量很少,可以使用哪些数据结构选项来代替哈希表?
哈希表
在哈希表中,通过对键调用哈希函数来存储值。
- 值不是按排序顺序存储的。
- 此外,由于哈希表使用键来查找将存储值的索引,因此可以在分摊 O(1) 时间内完成插入或查找(假设哈希表中的冲突很少)。
- 在哈希表中,还必须处理潜在的冲突。这通常通过链接来完成,这意味着创建一个所有值的链表,这些值的键映射到特定索引。
哈希表的实现:哈希表传统上是用链表数组实现的。当我们想要插入一个键/值对时,我们使用哈希函数将键映射到数组中的索引。然后将该值插入到该位置的链表中。
注意:链表中数组特定索引处的元素没有相同的键。相反,这些值的哈希函数(键)是相同的。因此,为了检索特定键的值,我们需要在每个节点中存储准确的键和值。
总而言之,哈希表将通过一个链表数组来实现,其中链表中的每个节点都保存着两部分数据:值和原始键。此外,我们要注意以下设计标准:
- 我们希望使用一个好的散列函数来确保密钥分布良好。如果它们分布不好,那么我们会发生很多碰撞,并且找到元素的速度会下降。
- 无论哈希函数有多好,我们仍然会遇到冲突,因此我们需要一种处理它们的方法。这通常意味着通过链表链接,但这不是唯一的方法。
- 我们可能还希望实现根据容量动态增加或减少哈希表大小的方法。例如,当元素数与表大小的比例超过某个阈值时,我们可能希望增加哈希表大小。这意味着创建一个新的哈希表并将条目从旧表转移到新表。因为这是一项昂贵的操作,所以我们要小心不要经常这样做。
STL地图
容器映射是包含在 C++ 标准库中的关联容器。这个类的定义在命名空间std的头文件“map”中。
STL Map 内部实现:
它被实现为一个自平衡的红黑树。可能两种最常见的自平衡树是红黑树和 AVL 树。为了在插入/更新后平衡树,两种算法都使用旋转的概念,其中树的节点被旋转以执行重新平衡。虽然在这两种算法中,插入/删除操作都是 O(log n),但在红黑树重新平衡旋转的情况下,这是一个 O(1) 操作,而对于 AVL,这是一个 O(log n) 操作,使得RB树在这方面效率更高,这也是重新平衡圣人比较常用的可能原因之一。
哈希表和STL映射的区别
- 空键: STL 映射允许一个空键和多个空值,而哈希表不允许任何空键或值。
- 线程同步:如果不需要线程同步,Map 通常比哈希表更受欢迎。哈希表是同步的。
- 线程安全: STL Maps 不是线程安全的,而 Hashmaps 是线程安全的,可以与多个线程共享。
- 值顺序:在 STL 映射中,值按排序顺序存储,而在哈希表中,值不按排序顺序存储
- 搜索时间:对于较小的数据,可以使用STL Map或二叉树(虽然需要O(log n)时间,但输入的数量可能小到可以忽略不计),对于大量数据,首选哈希表.
相关文章
- BST 相对于 hashmap 的优势
- JavaHashMap和HashTable的区别
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。