如果您真的是说输出顺序无关紧要,那么您需要std::nth_element,而不是std::partial_sort,因为它通常会更快一些。请注意,std::nth_element将第 n个元素放在正确的位置,因此您可以执行以下操作,这是 100% 的标准算法调用(警告:没有很好地测试;fencepost 错误可能性比比皆是):
template<typename RandomIterator, typename Compare>
void best_n(RandomIterator first,
            RandomIterator nth,
            RandomIterator limit,
            Compare cmp) {
  using ref = typename std::iterator_traits<RandomIterator>::reference;
  std::nth_element(first, nth, limit, cmp);
  auto p = std::partition(first, nth, [&](ref a){return cmp(a, *nth);});
  auto q = std::partition(nth + 1, limit, [&](ref a){return !cmp(*nth, a);});
  std::random_shuffle(p, q);  // See note
}
该函数采用三个迭代器,例如nth_element,其中nth是第 n个元素的迭代器,这意味着它是begin() + (n - 1))。
编辑:请注意,这与大多数 STL 算法不同,因为它实际上是一个包含范围。特别是 UB if nth == limit,因为它必须*nth是有效的。此外,没有办法请求best 0元素,就像没有办法请求第 0个元素一样std::nth_element。您可能更喜欢使用不同的界面;随意这样做。
或者你可以这样称呼它,在要求之后0 < k <= n:
best_n(container.begin(), container.begin()+(k-1), container.end(), cmp);
它首先用于nth_element将“最佳”k元素放在 position0..k-1中,以保证第 k个元素(或其中一个)位于 position k-1。然后它重新划分 position 前面的元素k-1,使相等的元素位于末尾,并重新划分 position 后面的元素k-1,使相等的元素位于开头。最后,它打乱相等的元素。
nth_element是O(n);这两个partition操作的总和为O(n); 并且random_shuffle是O(r)其中r是混洗的相等元素的数量。我认为所有的总结都是O(n)如此,它具有最佳的可扩展性,但它可能是也可能不是最快的解决方案。
注意:您应该使用std::shuffle而不是std::random_shuffle,将统一随机数生成器传递给best_n。但是我懒得写所有的样板来做这件事并测试它。对不起。