简体   繁体   English

STL max_element的复杂性

[英]Complexity of STL max_element

So according to the link here: http://www.cplusplus.com/reference/algorithm/max_element/ , the max_element function is O(n), apparently for all STL containers. 所以根据这里的链接: httpmax_element函数是O(n),显然对于所有STL容器。 Is this correct? 这个对吗? Shouldn't it be O(log n) for a set (implemented as a binary tree)? 不应该是一个集合的O(log n)(实现为二叉树)?

On a somewhat related note, I've always used cplusplus.com for questions which are easier to answer, but I would be curious what others think of the site. 在一个有点相关的说明中,我总是使用cplusplus.com来回答更容易回答的问题,但我很好奇其他人对该网站的看法。

It's linear because it touches every element. 它是线性的,因为它触及每个元素。

It's pointless to even use it on a set or other ordered container using the same comparator because you can just use .rbegin() in constant time. 使用相同的比较器甚至在集合或其他有序容器上使用它是没有意义的,因为你可以在恒定时间内使用.rbegin()

If you're not using the same comparison function there's no guarantee that the orders will coincide so, again, it has to touch every element and has to be at least linear. 如果您没有使用相同的比较函数,则无法保证订单会重合,因此,它必须触及每个元素并且必须至少是线性的。

Although algorithms may be specialized for different iterator categories there is no way to specialize them base on whether an iterator range is ordered. 虽然算法可能专门针对不同的迭代器类别,但根据迭代器范围是否有序,无法对它们进行专门化。

Most algorithms work on unordered ranges ( max_element included), a few require the ranges to be ordered (eg set_union , set_intersection ) some require other properties for the range (eg push_heap , pop_heap ). 大多数算法在无序范围(包括max_element )上工作,少数需要有序范围(例如set_unionset_intersection ),有些需要该范围的其他属性(例如push_heappop_heap )。

The max_element function is O(n) for all STL containers. 对于所有STL容器,max_element函数为O(n)。

This is incorrect, because max_element applies to iterators, not containers. 这是不正确的,因为max_element适用于迭代器,而不是容器。 Should you give it iterators from a set, it has no way of knowing they come from a set and will therefore traverse all of them in order looking for the maximum. 如果你从一个集合给它迭代器,它无法知道它们来自一个集合,因此将遍历所有它们以寻找最大值。 So the correct sentence is: 所以正确的句子是:

The max_element function is O(n) for all forward iterators 对于所有前向迭代器,max_element函数都是O(n)

Besides, if you know that you're manipulating a set, you already have access to methods that give you the max element faster than O(n), so why use max_element ? 此外,如果你知道你正在操作一个集合,你已经可以访问比o(n)更快地提供max元素的方法,那么为什么要使用max_element呢?

It is an STL algorithm, so it does not know anything about the container. 它是一个STL算法,所以它对容器一无所知。 So this linear search is the best it can do on a couple on forward iterators. 所以这个线性搜索是对前向迭代器上的一对最好的。

STL algorithms do not know what container you took the iterators from, whether or not it is ordered and what order constraints were used. STL算法不知道您从哪个容器中获取迭代器,是否已对其进行排序以及使用了哪些顺序约束。 It is a linear algorithm that checks all elements in the range while keeping track of the maximum value seen so far. 它是一种线性算法,可以检查范围内的所有元素,同时跟踪到目前为止看到的最大值。

Note that even if you could use metaprogramming techniques to detect what type of container where the iterators obtained from that is not a guarantee that you can just skip to the last element to obtain the maximum: 请注意,即使您可以使用元编程技术来检测迭代器从中获取的容器类型,也不能保证您可以跳到最后一个元素以获得最大值:

int values[] = { 1, 2, 3, 4, 5 };
std::set<int, greater<int> > the_set( values, values+5 );
std::max_element( the_set.begin(), the_set.end() ); //??

Even if the iterators come from a set, it is not the last, but the first element the one that holds the maximum. 即使迭代器来自一个集合,它也不是最后一个,而是第一个保持最大值的元素。 With more complex data types the set can be ordered with some other key that can be unrelated to the min/max values. 对于更复杂的数据类型,可以使用与最小/最大值无关的其他键来订购该集合。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM