如何从算法中找到递归关系

时间:2017-07-21 15:32:26

标签: c++ recursion big-o recurrence

我试图了解复发关系。我找到了一种通过递归来确定整数数组中最大元素的方法。以下是功能。第一次调用时,n是数组的大小。

int ArrayMax(int array[], int n) {
    if(n == 1)
        return array[0];
    int result = ArrayMax(array, n-1);
    if(array[n-1] > result)
        return array[n-1];
    else
        return result;
}

现在我想了解递归关系以及如何从那里获得big-O表示法。我知道T(n)= aT(n / b)+ f(n),但我不知道如何得到a和b应该是什么。

2 个答案:

答案 0 :(得分:3)

a是"有多少递归调用"和b是"您将数据分成多少部分直接进入"请注意,递归调用中的参数不必被n除以某种东西,一般来说,n的任何函数描述了你的大小如何数据已更改

例如,二进制搜索在每一层执行一次递归调用,将数据拆分为2,并在每一层执行常量工作,因此它具有T(n) = T(n/2) + c。合并排序每次将数据拆分为两次(拆分工作与n成比例)并对两个子阵列进行递归 - 因此您获得T(n) = 2T(n/2) + cn

在您的示例中,您有T(n) = T(n-1) + c,因为您正在进行一次递归通话,并且"拆分数据"通过每次减小1的大小。

要从中获取大O符号,您只需进行替换或扩展。通过您的示例,它很简单:

T(n) = T(n-1) + c = T(n-2) + 2c = T(n-3) + 3c = ... = T(0) + nc

如果您假设T(0) = c0,某些"基本常数",那么您将获得T(n) = nc + c0,这意味着已完成的工作位于O(n)

二进制搜索示例类似,但您必须进行替换 - 尝试让n = 2^m,并查看您可以使用它的位置。最后,得出例如的大O符号。 T(n) = T(sqrt(n)) + c是一项非常酷的练习。

编辑:还有其他方法可以解决递归关系 - Master Theorem是一种标准方法。但是证明并不是特别好,而且上述方法适用于我曾经应用过的每一次重复。而且......嗯,它比将值插入公式更有趣。

答案 1 :(得分:0)

在你的情况下,递归关系是:

T(n) = T(n-1) + constant

Master定理说:

T(n) = aT(n/b) + f(n) where a >= 1 and b > 1

这里的主定理不能应用,因为对于主定理 b应大于1 (b>1) 在您的情况下b=1