C++ STL set implementation
C++ STL set implementation
为什么c++集是作为二叉树而不是作为哈希集来实现的,与二叉树提供的O(log n)相比,哈希集可以提供O(1)的平均情况复杂度?
因为c++集合是由T
的比较操作符排序的,这使得以可预测的方式迭代成员成为可能。如果你知道你要做的就是插入,测试成员关系,和/或删除元素,那么std::unordered_set
,它实现了一个哈希集,从c++ 11开始就存在了。
根据John Nagle的说法,从2006年发布到comp.lang.c++.moderated:
真正的原因是写这封信的人规范的哈希表部分没有及时完成。就是这样。
标准化过程就是这样。
这里有两个因素:
- 二叉树和基于哈希的关联集都是有用的
- 最初的STL只实现了前者,因为缺乏时间来完成"政治";标准化;SGI、GNU、MS、boost等已经提供了多年的非标准哈希版本,c++ 11引入了
unordered_set
这些要点将在下面讨论。
都是有用的
有很多优点/缺点,并且两者都可以(从c++ 11开始)让程序员选择。基于哈希的集合是不可用的,因为没有及时就实现达成一致,无法将它们包含在早期的标准中。
-
set
迭代是按排序顺序进行的,而散列容器unsorted_set
是有效的随机顺序遍历-
set
支持lower_bound
,upper_bound
,这在unsorted_set
上是不实际的
-
-
set
使用一个比较函数(默认情况下包含类型的operator<
,而unordered_set
需要一个哈希函数(默认情况下为某些类型提供,但根据您的实际密钥,它们可能相当平庸,高质量的哈希可能很耗时)和一个键相等函数 - 对于较小的N值可能更快——不是每个人都要处理数十亿个元素,所以提供选择是明智的,即使是从性能的角度来看
- 对于小对象的内存使用可能存在显著差异,尽管我不确定跨实现的总体指导方针是什么,所以如果您关心 ,可以建议在您的程序中进行测量。
- 在添加元素时,插入到
std::unordered_set
中的现有迭代器可能会失效(具体何时失效请参见23.2.5p14),而插入到std::map
中的迭代器永远不会因插入而失效(但指向unordered_set
元素的指针和引用仍然有效)。
为什么早期的c++标准没有基于哈希的集合
摘自对Stepanov的采访:
问题:我在d.m asser网站上发现了两个哈希表实现,它们都很好用,而且相当聪明——比类库中常见的哈希表聪明得多。为什么散列表不包含在STL中?
答:政治。他们必须在里面。我们新的STL实现确实包含了它们。一般来说,我们需要开发一种向STL添加东西的机制。毕竟,STL是一个可扩展的框架,它需要被扩展。有许多数据结构是缺失的,例如,单链表、矩阵和图。SGI愿意带头扩展STL。
(访问网址:http://www.stlport.org/resources/StepanovUSA.html)
相关文章:
- 为什么我无法更改"set<set>"循环中的值<int>
- 对于set上的循环-获取next元素迭代器
- 在声明中合并两个常量"std::set"(不是在运行时)
- 有没有办法对std::unordered_set、std::unrdered_map、std::set、std::map
- 将 std::set 与基于键的比较器一起使用
- 如何使用set实现无序数据结构?
- 使用运算符调用 void 函数时出错<set>
- Softmax Implementation in C++
- 修改"std::set"中用户定义类型的值
- 生成提升::hana::set 的常量表达式问题
- 如何在构造函数参数中初始化"std::set"?
- 如何使用 lower_bound/upper_bound 从 std::set 获取索引号?
- 如何在 C++ 中转发声明 std::set?
- 重构使用动态强制转换的 std::set 的比较运算符
- set::find 查找不存在的元素
- 为什么 std::set.erase(first, last) 会影响从中获取 (first, last) 的容器?
- 将 std:set<int32_t> 复制到 std::set <uint32_t>的好方法
- 错误 C2676:std::set::const_iterator 没有运算符 + 函数?
- std::set 是否将对象连续存储在内存中?
- C++ STL set implementation