Unordered_Map 查找时间
Posted
技术标签:
【中文标题】Unordered_Map 查找时间【英文标题】:Unordered_Map Lookup Time 【发布时间】:2014-10-16 22:16:25 【问题描述】:C++ 库中的内置映射和集合(包括 unordered_map 和 multimap)要求 find 函数(用于查找特定元素)使用迭代器来遍历元素。 C++ 参考站点声称使用这些数据结构查找元素平均需要恒定时间,就像常规哈希表一样。但是在找到元素之前,迭代器是否必须遍历整个列表,平均花费 O(n) 时间?
【问题讨论】:
无序映射是一个哈希表,查找桶是恒定的时间(不考虑哈希键所需的时间)。碰撞通常通过一个简单的列表来处理。 @Chad 我知道无序映射是一个哈希表,查找存储桶通常是在恒定时间内完成的。但是你怎么看?你会使用查找功能吗? 【参考方案1】:你的说法不正确:
map
、set
、multimap
和 multiset
通常实现为二叉树(例如:在 VS 中实现为红黑树),在这种情况下 find 方法使用在一个节点中的属性搜索键left child is less
比节点(根据比较器)和the right child is greater
比节点(根据比较器)。这给出了标准要求的 O(log n)。
在unordered_map
和unordered_set
实现为哈希表的情况下,通常实现为桶的集合(例如:std::vector<Bucket>
),桶实现为unordered_map
(例如:std::vector<elem>
或std::list<elem>
),假设散列函数是常数时间(或不包括时间),则在此集合中的搜索是平均常数时间O(1)(散列给出放置元素的桶,如果桶搜索中的元素很少,那么目标元素)。最坏的情况是当所有元素都在同一个桶中时,在这种情况下,目标元素的搜索需要遍历桶中的所有元素,直到找到或没有找到(在 O(n) 中)。借助良好的散列函数,您可以增加对桶中元素进行足够均匀分割的概率(获得预期的恒定时间)。
注意:find
函数返回 iterator
并不意味着使用迭代器来搜索请求的元素。
【讨论】:
所以 find 函数不需要 O(n) 时间来搜索? 在unordered_map
和类似的情况下,搜索最多可能需要 O(n) 但这是最坏的情况,通常需要 O(1),都取决于哈希函数如何均匀分布桶中的元素(目标是每个桶具有相同数量的元素,最坏的是所有元素都在同一个桶中)。数据结构的实际状态越 close 越接近 best O(1) 或 worst O(n) 情况,越接近运行时将是。通常接近最坏的情况不会发生太多(它需要结合非常糟糕的散列函数和奇怪的数据)以上是关于Unordered_Map 查找时间的主要内容,如果未能解决你的问题,请参考以下文章
使用 string_view 在 unordered_map 中查找
使用 lambda 函数在 std::unordered_map 中查找最小值