搜索算法以查找列表中的k个最低值

时间:2012-07-10 05:28:32

标签: c++ c algorithm search selection

我有一个包含 n 双值的列表,我需要在该列表中找到 k 最低的double值

  • k 远小于 n
  • 带有 n 双值的初始列表是随机排序的
  • 找到的 k 最低双精度值不需要排序

您会推荐什么算法?

目前我使用 Quicksort 对整个列表进行排序,然后从排序列表中取出第一个 k 元素。我希望应该有一个更快的算法。

感谢您的帮助!!!

5 个答案:

答案 0 :(得分:10)

您可以为解决方案建模以匹配nlargest() code in Python's standard library

  • 在maxheap上修复第一个 k 值。
  • 迭代剩余的 n - k 值。
  • 将每个元素与堆顶部的元素进行比较。
  • 如果新值较低,请执行 heapreplace 操作(使用新值替换最顶层的堆元素,然后向下筛选)。

算法效率惊人。例如,当n = 100,000且k = 100时,对于随机排列的输入,比较的数量通常约为106,000。这只是略多于100,000次比较,以找到单个最小值。而且,它比整个数据集中的完全快速排序少做二十倍的比较。

各种算法的相对强度在http://code.activestate.com/recipes/577573-compare-algorithms-for-heapqsmallest

进行了研究和总结

答案 1 :(得分:8)

您可以使用selection algorithm找到第k个最低元素,然后迭代并返回它以及低于它的所有元素。如果列表可以包含重复项,则必须完成更多工作(确保您不会得到所需的更多元素)。
这个解决方案是O(n)。 选择算法在C ++中实现为nth_element()

另一个替代方法是使用大小为k的最大heap ,并迭代元素,同时保持堆以容纳所有k个最小元素。

for each element x:
   if (heap.size() < k):
      heap.add(x)
   else if x < heap.max():
      heap.pop()
      heap.add(x)

完成后 - 堆包含k个最小元素。
此解决方案为O(nlogk)

答案 2 :(得分:2)

从C ++标准库中查看partial_sort算法。

答案 3 :(得分:2)

您可以使用std::nth_element。这是O(N)的复杂性,因为它不对元素进行排序,它只是将它们排列成使得某个N下的每个元素都小于N.

答案 4 :(得分:0)

你可以使用选择排序,需要O(n)来选择第一个最低值。一旦我们在位置1上设置了这个最低值,我们就可以重新扫描数据集以找出第二个最低值。并且可以做到直到我们具有第k个最低值。这样,如果k足够小于n,那么我们将得到复数kn,它相当于O(n)......