动态排序的STL容器

时间:2008-09-15 21:58:38

标签: c++ stl containers

我对STL很新,所以我想知道是否有可动态排序的容器?目前我的想法是将矢量与各种排序算法结合使用,但我不确定是否有更合适的选择,因为(可能)线性复杂性将条目插入到排序向量中。

为了澄清“动态”,我正在寻找一个可以在运行时修改排序顺序的容器 - 例如按升序排序,然后按降序重新排序。

12 个答案:

答案 0 :(得分:17)

你想看看std :: map

std::map<keyType, valueType>

地图基于&lt;运算符为keyType提供。

std::set<valueType>

同样按照&lt;模板参数的运算符,但不允许重复元素。

std::multiset<valueType>

与std :: set的作用相同但允许相同的元素。

我高度推荐Josuttis提供的“C ++标准库”以获取更多信息。它是对std库的最全面的概述,非常易读,并且充满了模糊和不那么模糊的信息。

此外,如26日中的第17条所述,Meyers的Effective Stl值得一读。

答案 1 :(得分:10)

如果你知道你要按单个值升序和降序排序,那么set就是你的朋友。如果要在相反方向“排序”,请使用反向迭代器。

如果您的对象很复杂,并且您将根据对象中的成员字段以多种不同方式进行排序,那么使用向量和排序可能会更好。尝试一次完成插入,然后调用一次排序。如果这不可行,那么deque可能比大型对象集合的矢量更好。

我认为如果您对 级别的优化感兴趣,最好使用实际数据来分析您的代码。 (这可能是这里任何人都可以给出的最佳建议:如果你只是在蓝月亮中做一次,那么你可以在每次插入后调用sort。)

答案 2 :(得分:4)

听起来你想要multi-index container。这允许您创建容器并告诉该容器您可能想要遍历其中的项目的各种方式。然后容器保留多个项目列表,并在每次插入/删除时更新这些列表。

如果您真的想要对容器进行重新排序,可以在任何std::dequestd::vector或甚至是简单的C风格数组上调用std::sort函数。该函数采用可选的第三个参数来确定如何对内容进行排序。

答案 3 :(得分:3)

stl没有提供此类容器。您可以定义自己的,由set/multisetvector支持,但每次调整排序函数时,您都必须通过调用sort重新排序(对于vector)或创建新集合(set/multiset)。

如果您只想从增加排序顺序更改为减少排序顺序,可以通过调用rbegin()rend()而不是begin()和{{{}来使用容器上的反向迭代器1}}。 end()vector都是可逆容器,因此这适用于任何一种。

答案 4 :(得分:2)

std::set基本上是一个已排序的容器。

答案 5 :(得分:1)

你绝对应该使用一套/地图。就像hazzen所说,你得到O(log n)插入/查找。你不会得到一个有序矢量;您可以使用二进制搜索获得O(log n)查找,但插入是O(n),因为插入(或删除)项目可能会导致向量中的所有现有项目被移位。

答案 6 :(得分:1)

这不是那么简单。根据我的经验,插入/删除的使用频率低于查找。排序向量的优点是它占用更少的内存并且更加缓存友好。如果碰巧有与STL地图兼容的版本(就像我以前链接过的那样),很容易来回切换并在每种情况下使用最佳容器。

答案 7 :(得分:1)

理论上,关联容器(set,multiset,map,multimap)应该是你最好的解决方案。

在实践中,它取决于您投入的元素的平均数量。 对于少于100个元素,矢量可能是最佳解决方案,原因如下: - 避免连续分配 - 释放 - 由于数据位置而缓存友好 这些优势可能会超越连续排序。 显然,这还取决于你必须做多少插入 - 删除。你打算进行每帧插入/删除吗?

更一般地说:你在谈论性能关键型应用吗?

记得不要过早地优化......

答案 8 :(得分:1)

答案一如既往地取决于。

setmultiset适用于保持项目的排序,但通常针对平衡的添加,删除和提取集进行优化。如果你有男子气概的查找操作,那么排序的vector可能更合适,然后使用lower_bound来查找元素。

此外,您在运行时使用不同顺序的第二个要求实际上意味着setmultiset不合适,因为谓词不能在运行时修改。

因此,我建议使用有序矢量。但是请记住将相同的谓词传递给lower_bound,因为结果将是未定义的,并且如果传递错误的谓词,则很可能是错误的。{/ p>

答案 9 :(得分:1)

Set和multiset使用底层二进制树;您可以定义&lt; =运算符供您自己使用。这些容器保持自己的排序,因此如果要切换排序参数,可能不是最佳选择。如果你想要相当多的话,矢量和列表可能是最好的;一般来说,list有自己的排序(通常是mergesort),你可以在向量上使用stl二进制搜索算法。如果插入将占主导地位,列表优于矢量。

答案 10 :(得分:0)

STL地图和集合都是已排序的容器。

我是Doug T的第二本书推荐书 - Josuttis STL书籍是我见过的最好的学习书和参考书。

Effective STL也是一本很好的书,用于学习STL的内在细节以及你应该和不应该做什么。

答案 11 :(得分:0)

对于“STL兼容”排序向量,请参阅A. {3}}的A. Alexandrescu的AssocVector。