【发布时间】:2021-11-12 18:05:51
【问题描述】:
在我接触到算法std::nth_element 之前,我几乎了解了许多STL 算法。我被困住了;我不知道它是如何工作的,但确实如此。
为了教育和理解,有人可以向我解释算法std::nth_element 的工作原理吗?
std::vector<int> v{ 9, 3, 6, 2, 1, 7, 8, 5, 4, 0 };
std::nth_element(v.begin(), v.begin() + 2, v.end());
for (auto i : v)
std::cout << i << " ";
std::cout << '\n';
输出:
1 0 2 3 6 7 8 5 4 9
- 那么
nth元素在哪里? - 算法的作用和作用是什么?
- 它会进行某种部分排序吗?
以下是来自 cppreference.com 的一些解释:
nth_element是一种部分排序算法,它重新排列 [first, last) 中的元素,使得:
- 如果 [first, last) 已排序,则 nth 指向的元素将更改为该位置将出现的任何元素。
- 此新的第 n 个元素之前的所有元素都小于或等于新的第 n 个元素之后的元素。 更正式地说,nth_element 以升序对范围 [first, last) 进行部分排序,以便对于范围 [first, nth ) 以及 [nth, last) 范围内的任何 j。如果范围已完全排序,则放置在第 n 个位置的元素正是出现在该位置的元素。
nth 可能是结束迭代器,在这种情况下该函数无效。
- 我仍然对此感到困惑。什么是第 n 个元素以及如何实现这样的可能算法?为了教育起见,我模仿了许多 STL 算法。非常感谢!
【问题讨论】:
-
So where is nth element here?“在哪里”是什么意思?How and what the algorithm does?正是您引用的文档中所述的内容。Does it do some sort of partial sorting?嗯...nth_element is a partial sorting algorithm -
如果您无法理解文档,请告诉我们您不理解哪些行/语句。
-
也许要回答的一个更有启发性的问题是“在什么情况下有人会发现调用
nth_element()很有用”? (大概这个函数不是为了让 STL 变大而编写的;一定是有人想要解决一些常见问题,促使他们编写它并将其包含在 STL 中) -
@ItachiUchiwa:第 n 个元素指的是位置,而不是值。
v.begin() + 2是第三个元素(索引2,从 0 开始)。如果整个数组已排序,2将出现在该位置,nth_element会发生这种情况。所有其他元素的位置都是半随机的,除了保证小于以索引2结尾的元素的所有元素都在它之前,所有大于它的元素都在它之后。 Introselect 是推荐算法。 -
@JeremyFriesner:我想它的用例类似于
partial_sort。您需要在某个排名阈值处分离最大和最小元素,但不需要对元素进行排序以获得有用的结果。例如,要获得数据集中间 90% 的平均值,您需要将两边的 5% 分离为异常值,但中间 90% 不需要排序。您可以使用nth_element一次来分离底部的 5%,然后再次(在枢轴右侧 95% 处)分离顶部的 5%。然后是线性传递来计算平均值。三个O(n)步骤,根本没有O(n log n)排序。
标签: c++ algorithm nth-element