递归方法的大O.

时间:2012-07-31 22:57:20

标签: recursion big-o

我很难确定简单递归方法的大O.我无法解决多次调用方法时发生的事情。我会更加具体地讲述我的困惑,但目前我正在尝试回答一些问题,而不是想作弊,我要求任何回复这篇文章的人想出一个简单的递归方法,提供所述方法的大O的简单解释。 (最好是Java ...我正在学习的一种语言。)

谢谢。

2 个答案:

答案 0 :(得分:32)

您也可以递归地定义订单。例如,假设你有一个函数f。计算f(n)需要k步。现在你要计算f(n + 1)。让我们说f(n + 1)调用f(n)一次,然后f(n + 1)将k +调整为一些常数步长。每次调用都需要额外的一些常量步骤,因此这个方法是O(n)。

现在看另一个例子。假设您通过添加前两个结果来天真地实施斐波纳契:

fib(n) = { return fib(n-1) + fib(n-2) }

现在假设您可以在大约k步中计算fib(n-2)和fib(n-1)。要计算fib(n),您需要k + k = 2 * k步。现在假设您要计算fib(n + 1)。所以你需要两倍于fib(n-1)的步数。所以这似乎是O(2 ^ N)

不可否认,这不是很正式,但希望通过这种方式你可以有一点感觉。

答案 1 :(得分:15)

你可能想参考主定理来找到递归方法的大O.以下是维基百科文章:http://en.wikipedia.org/wiki/Master_theorem

您想要像树这样的递归问题。然后,考虑树的每个级别和所需的工作量。问题通常分为3类,根重(第一次迭代>>树的其余部分),平衡(每个级别具有相同的工作量),叶重(最后一次迭代>>树的其余部分)。

以合并排序为例:

define mergeSort(list toSort):
    if(length of toSort <= 1):
        return toSort
    list left = toSort from [0, length of toSort/2)
    list right = toSort from [length of toSort/2, length of toSort)
    merge(mergeSort(left), mergeSort(right))

你可以看到每次调用mergeSort依次调用另外两个原始长度为1/2的mergeSorts。我们知道合并过程需要的时间与合并的值的数量成正比。

然后,递归关系为T(n)= 2 * T(n / 2)+ O(n)。这两个来自2个呼叫,而n / 2来自每个呼叫,只有一半的元素。但是,在每个级别都有相同数量的元素n需要合并,因此每个级别的常量工作是O(n)。

我们知道工作是均匀分布的(O(n)每个深度)并且树是log_2(n)深,因此递归函数的大O是O(n * log(n))。