所以根据这里的链接:http://www.cplusplus.com/reference/algorithm/max_element/,max_element
函数是O(n),显然对于所有STL容器。它是否正确?不应该是一个集合的O(log n)(实现为二叉树)?
在一个有点相关的说明中,我总是使用cplusplus.com来回答更容易回答的问题,但我会好奇其他人对该网站的看法。
答案 0 :(得分:8)
它是线性的,因为它触及每个元素。
甚至在使用相同的比较器的集合或其他有序容器上使用它是没有意义的,因为你可以在恒定时间内使用.rbegin()
。
如果您没有使用相同的比较功能,则无法保证订单会重合,因此,它必须触及每个元素并且必须至少是线性的。
虽然算法可能专门针对不同的迭代器类别,但根据迭代器范围是否有序,无法对它们进行专门化。
大多数算法适用于无序范围(包括max_element
),少数算法要求排序范围(例如set_union
,set_intersection
)某些算法需要范围的其他属性(例如{ {1}},push_heap
)。
答案 1 :(得分:3)
对于所有STL容器,max_element函数为O(n)。
这是不正确的,因为max_element
适用于迭代器,而不适用于容器。如果你从一个集合给它迭代器,它无法知道它们来自一个集合,因此将遍历所有它们以寻找最大值。所以正确的句子是:
对于所有前向迭代器
,max_element函数为O(n)
此外,如果您知道自己正在操作集合,那么您已经可以访问比O(n)更快的最大元素的方法,那么为什么要使用max_element
?
答案 2 :(得分:0)
这是一个STL算法,所以它对容器一无所知。因此,这种线性搜索是对前向迭代器上的几个最好的。
答案 3 :(得分:0)
STL算法不知道您从哪个容器获取迭代器,是否已对其进行排序以及使用了哪些顺序约束。它是一种线性算法,可以检查范围内的所有元素,同时跟踪到目前为止看到的最大值。
请注意,即使您可以使用元编程技术来检测迭代器从中获取的容器类型,也不能保证您可以跳到最后一个元素以获得最大值:
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() ); //??
即使迭代器来自一个集合,它也不是最后一个,而是第一个保持最大值的元素。对于更复杂的数据类型,可以使用与最小/最大值无关的其他键来订购该集合。