关于懒惰评估及其效率的澄清

时间:2013-10-09 18:00:50

标签: lazy-evaluation haskell

我在Real World Haskell上发表了以下句子:

  

懒惰的评价有一些怪异的效果。假设我们想要找到   k个未排序列表的k个最小值元素。在传统的   语言,显而易见的方法是对列表进行排序并采取   前k个元素,但这很贵。为了提高效率,我们愿意   而是写一个特殊的函数,在一次传递中获取这些值,   它必须执行一些中等复杂的簿记。在   Haskell,排序然后采取的方法实际上表现良好:懒惰   确保列表仅排序足以找到k minimal   元件。

他们为此提供了代码实现:

minima k xs = take k (sort xs)

但是这样吗?我想即使在Haskell中它也应该完整地列出k元素。 (想象一下,列表末尾的数字最小)。我在这里错过了什么吗?

1 个答案:

答案 0 :(得分:1)

(只需将我的评论放在这里回答)遍历整个列表并不等同于对其进行排序。假设执行快速排序,您可以在其中围绕数据透视表对列表进行分区,然后递归地对列表的左半部分和右半部分进行排序。如果您只是要求左半部分的元素,则无需对右半部分进行排序。可以递归地应用此参数。因此,如果您在排序后从k长度列表中提取n个元素,则复杂度为O(n + klog k)而非O(n log n)。正如@MoFu指出的,Heinrich有一篇很好的博文here