std::set迭代顺序是否始终根据C++规范升序

Is the std::set iteration order always ascending according to the C++ specification?

本文关键字:范升序 C++ 升序 迭代 set 顺序 是否 std      更新时间:2023-10-16

此处http://www.cplusplus.com/reference/stl/set/我读到C++中的std::set"通常"实现为一个树(红黑树?),并且它是排序的。

我不明白,这是否意味着根据规范集合的迭代顺序总是升序?或者它只是"通常的实现细节",有时某些库/编译器可能会违反这个约定?

根据C++标准,std::set中元素的迭代按std::less或可选比较谓词模板参数确定的排序顺序进行。

(同样根据C++标准,插入、查找和删除最多需要O(lgn)时间,因此平衡搜索树是std::set目前唯一可行的实现选择,尽管标准没有强制使用红黑树。)

这意味着std::set将在内部将其元素存储为排序树。但是,规范中没有说明排序顺序。默认情况下,std::set使用std::less,因此将按从低到高的顺序排列。然而,您可以使用以下模板参数使排序功能成为您想要的任何功能:

std::set<valueType, comparissonStruct> myCustomOrderedSet;

例如:

std::set<int, std::greater<int> > myInverseSortedSet;

struct cmpStruct {
  bool operator() (int const & lhs, int const & rhs) const
  {
    return lhs > rhs;
  }
};
std::set<int, cmpStruct > myInverseSortedSet;

事实上,你链接的网站上也提供了这些例子。这里更具体地说:设置构造函数。

按规范,集合的迭代顺序总是递增的

是的,如果你按顺序打印,set的值总是升序的。正如描述中所说,它通常使用红黑树(RBT)来实现,但编译器编写者可以选择违反这一点,但通常会坚持RBT的主题,因为任何其他实现都无法实现set的任务。

默认比较器较少,因此集合将按升序排列。若要更改此设置,可以指定另一个现有或自定义比较器作为模板参数。

C++11 N3337标准草案

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf

23.2.4"关联容器"上写着:

1关联容器提供了基于关键字的数据快速检索。图书馆提供了四种基本的关联容器:集合、多重集合、贴图和多重贴图。

和:

10关联容器的迭代器的基本特性是它们遍历容器按键的非降序排列,其中非降序由用于构建它们。

所以,订单由C++标准保证。

这就是为什么gcc 6.4.0将其实现为BST而不是hashmap的原因:C++中STL集的底层数据结构是什么?

与此形成对比的是C++11unordered_set,后者倾向于通过哈希图实现提供更好的性能,代价是受到更多限制(没有自由排序遍历),如所示

  • C++中STL集的底层数据结构是什么
  • 为什么有人会使用set而不是unordered_set?例如使用散列集