【问题标题】:What is the running time of this Haskell merge code这个 Haskell 合并代码的运行时间是多少
【发布时间】:2014-12-08 16:33:10
【问题描述】:

我想出了这段代码,它采用升序排列的两个 SORTED 列表,然后将这两个列表合并为一个列表,保持升序排序。我试图分析它,看看它的时间复杂度是多少。我的信念是,在最坏的情况下,我们将不得不遍历整个列表,并且由于有 2 个列表,我们将不得不进行嵌套递归,这意味着最坏情况的 O(n^2) 时间。但是,由于我们在递归之前比较了两个元素的大小,我认为这可能是 O(log n) 时间。如果我错了,请纠正我。谢谢

这是我的递归:

mergeLists::[Integer]->[Integer]->[Integer]
mergeLists [] []        =[]
mergeLists [] (y:ys)    =(y:ys)
mergeLists (x:xs) []    =(x:xs)

mergeLists (x:xs) (y:ys)
 |(x<y)                 =x:mergeLists xs (y:ys)
 |otherwise             =y:mergeLists (x:xs) ys

【问题讨论】:

  • 通常定义为左偏,即当x==y时,拉x,而不是y:| y&gt;x = y : ...

标签: performance algorithm haskell recursion


【解决方案1】:

您的mergeLists 将采用 O(n+m) 其中 nm 是输入列表的长度。这可以通过对 n+m 的数学归纳很容易证明,递归调用的次数最多为 n+m

  • 对于前 3 种情况,没有递归,因此递归调用的次数比 n+m 小。
  • 对于最后两种情况:在每种情况下,嵌套调用都接收原始列表之一,另一个缩短 1。因此我们可以使用归纳原理告诉我们嵌套调用最多会进行 n+m-1 次递归调用,因此所讨论的调用最多会进行 n+m 次调用。

【讨论】:

    【解决方案2】:

    时间效率将是 O(n),因为这两个列表已被假定为升序。除了传递给函数的每个列表中的元素数量之外,您不需要递归或执行任何比较部分。

    啊,卡里姆已经回答了这个问题。我将通过提供对时间和空间效率的 Big-O 表示法的理解来使其变得更好。 Big-O 表示法用于表示在一组任意大小的数据上的算法性能的基本概念。很明显,随着算法工作数据集的增加,执行操作的实际时间也会增加。如果时间的增加是线性确定的(即每个数据成员将算法的实际完成时间增加了与所有其他元素相同的量),那么算法的时间效率被称为“n 阶”或 O(n )。您的算法就是这种情况。

    要了解有关 Big-O 表示法的更多信息,请参阅 StackOverflow 上的另一个问题:What does O(log n) mean exactly?

    【讨论】:

      【解决方案3】:

      因为列表已经排序..那么合并时间将是 O(n) 而 n 是两个列表的总大小。

      它将像合并排序一样工作:http://www.vogella.com/tutorials/JavaAlgorithmsMergesort/article.html

      【讨论】:

        猜你喜欢
        • 2019-03-27
        • 1970-01-01
        • 1970-01-01
        • 2017-01-29
        • 1970-01-01
        • 2011-08-30
        • 2016-01-17
        • 2016-10-30
        • 2013-10-05
        相关资源
        最近更新 更多