调用std::nth_element后第n个元素之前的元素顺序

Order of elements before nth element after call to std::nth_element

本文关键字:元素 顺序 后第 nth std element 调用      更新时间:2023-10-16

我感兴趣的是找到向量中等于中值的第一个(最左边)元素的最有效方法。找到中位数很简单:

std::nth_element(first, middle, last);
auto median = *middle;

但是,如果输入类似于{2,2,2,2,1},那么在调用std::nth_element之后,中间元素之前将有2s。我必须搜索中间左边的所有值吗?还是可以保证2s都是相邻的?

另一种提问方式是,在如上所述调用std::nth_element之后,{2,1,2,2,2}是否可能,或者{1,2、2,2}是否有保证?在后一种情况下,我可以从中间向左搜索。在前者中,我必须从第一个搜索到中间,这效率较低。从实证检验来看,后一种情况似乎成立。想知道是否有人有一个明确的答案,或者我是否遗漏了一些角落的案例。

文档仅保证:

  • 如果对[first,last)进行排序,则第n个指向的元素将更改为该位置中出现的任何元素
  • 该新的第n个元素之前的所有元素都小于或等于新的第N个元素之后的元素

注意,有no保证第n个元素之前或之后的元素以任何特定的顺序出现,只要之前的元素小于或等于它(并且通过扩展,由于它是第n个元件的性质,它之后的元素大于或等于它);CCD_ 1和CCD_。

第n个元素不保证第n个之前元素的顺序。

如果不聚集等于第n个的元素,或者在小列表中进行排序,可能很难实现,所以这可能就是你所看到的。


这可能有助于理解第n个元素是如何实现的:这只是一个例子。

实现第n个元素的一种方法是做中值为5。把你的收藏品分成5块。对每个束进行排序(O(1)*O(n))。现在,在5个元素块的中值上重复,以找到其真正的中值(使用第n个元素)。

最终,你会得到一个接近中间的元素(在0.3和0.7之间),它需要线性时间。(

对序列进行分区(线性时间),现在元素在序列中的顺序(通过计数)。

如果它是第n个元素,并且你在为第k个和第k个而loking

当你用线性时间算法搜索一个指数较小的区域时,整个算法就是线性时间。

请注意,这可能会严重打乱元素的顺序;没有任何保证平等的elemenra是一个相邻的。

请参阅https://en.m.wikipedia.org/wiki/Median_of_medians了解更多详细信息。