C++ STL set implementation

C++ STL set implementation

本文关键字:implementation set STL C++      更新时间:2023-10-16

为什么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)