【问题标题】:Set Implementation in C++?在 C++ 中设置实现?
【发布时间】:2013-04-07 15:59:40
【问题描述】:

根据以下链接 - C++ 的 STL 中的 http://www.cplusplus.com/reference/set/set/ 集通常实现为二叉搜索树,我能够在诸如整数或字符集或浮点数或字符串集等情况下衡量数据类型的行为在这些情况下,很容易看到 BST 排序被强加于集合元素,但考虑到集合的二叉搜索树数据结构实现,我无法想象以下数据类型是如何使用二叉搜索树实现的:

  1. set<vector<int>>set<vector<string>>set<vector<double>>set<list<int>>
  2. set<map<int, int>>
  3. set<stack<int>>

或者对于许多其他数据类型,如何为这些类型分配内存以及如何维护排序。

此外,我无法弄清楚以下内容,每当将新向量添加到集合中时,集合数据类型是否会在内部检查集合中的所有向量的相似性或所有映射的相似性,这些是我我无法弄清楚。如果有人能帮我将这些概念形象化,那就太好了。

提前致谢:)

【问题讨论】:

  • 内存分配相同(例如,new intnew vector<double>),排序也相同(使用operator<)(例如,here's a link 对某些vector 的比较运算符)。

标签: c++ algorithm data-structures stl


【解决方案1】:

该集合使用严格的弱排序来确定每个元素的位置。这是默认使用std::less<T> 完成的。这将导致调用operator<(const T&, const T&)。现在,诸如std::vectorhave such operators 之类的容器只对所有元素执行lexicographical comparison。这就是std::set<std::vector<int>> 开箱即用的方式。

当插入一个新元素时,集合不必检查所有元素。插入是一种对数复杂性操作,这就是为什么实现往往是自平衡二叉树的原因(我用这种相当奇怪的因果关系来表述它,因为 C++ 标准没有指定实现应该是什么样的,只是它应该如何表现。 )

【讨论】:

  • 如果你在一个集合中插入一个向量,那么插入怎么可能是一个对数时间操作,这有点复杂,我无法弄清楚
  • @Coder 是二叉搜索树的重点。如果您有一个平衡树,则执行 O(log_2(N)) 比较以找到正确的位置。可以将其视为针对给定值搜索正确的位置。
  • 实现如何决定在树中的哪个位置插入向量以及在什么基础上进行什么样的字典比较?
  • @Coder 由实现决定从哪里开始,但一个很好的猜测是中间节点。容器或std::strings 之间的字典比较基本上将operator< 应用于LHS 和RHS 中的一对元素。
【解决方案2】:

无论T 是什么具体类型,set<T> 的工作方式始终相同。在插入时,它通过使用std::less<T>(默认调用operator<)将新元素与各种现有元素进行比较来确定在树* 中放置新元素的位置。如果operator< 没有为T 重载,那么它将无法编译。

因此,如何对T 的实例进行排序的细节是从如何维护一个集合的细节中抽象出来的。


* 注意std::set 不必使用树;这只是一个典型的实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-14
    • 1970-01-01
    • 2017-06-04
    • 2014-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多