找到递归算法的复杂性?

时间:2014-01-30 18:59:23

标签: algorithm recursion complexity-theory big-o

我在查找递归方法的复杂性方面遇到了麻烦。我有一个算法,按升序对数组元素进行排序。基本上我所做的是写下算法中的每一步以及最佳/最差情况下的执行次数,然后取每个案例的总和并找到Big-O / Big-Omega。但我不确定递归电话?我是否记下了在方法中调用它的次数,或者它总被调用的次数(可能会有所不同)?

假设我有一个数组A = [5,4,3,2,1](这是最糟糕的情况,如果我没有弄错的话),那么我首先在​​第一个数组中执行一次while循环(参见下面的算法),然后在第二个while循环中再次向后,然后是递归调用。总的来说,我调用了我的方法一次(原始调用),然后是第二次调用,然后是第三次调用(没有进入if语句)。因此,对于n = 5个元素的数组,这是3次。但是在方法本身内部,递归调用会发生一次。我很困惑! :S

此外,在考虑时间复杂度与空间复杂度时有何不同?任何提示/建议都会有所帮助。

谢谢!

以下是给定的算法:

Algorithm MyAlgorithm(A, n) 
    Input: Array of integer containing n elements 
    Output: Possibly modified Array A 
        done ← true 
        j ← 0 
        while j ≤ n - 2 do 
            if A[j] > A[j + 1] then 
                swap(A[j], A[j + 1]) 
                done:= false 
            j ← j + 1 
        end while 
        j ← n - 1 
        while j ≥ 1 do 
            if A[j] < A[j - 1] then 
                swap(A[j - 1], A[j]) 
                done:= false 
            j ← j - 1 
        end while 
        if ¬ done 
            MyAlgorithm(A, n) 
        else 
           return A

这是我的解决方案:

Statement                Worst Case         Best Case
------------------------------------------------------------------
done = true                  1                  1
j = 0                        1                  1
j <= n-2                     n                  n
A[j] > A[j+1]                n-1                n-1
swap(A[j], A[j+1])           n-1                0
done = false                 n-1                0
j = j + 1                    n-1                n-1
j = n - 1                    1                  1
j >= 1                       n-1                n-1
A[j] < A[j-1]                n-1                n-1
swap(A[j-1], A[j])           n-1                0
done = false                 n-1                0
j = j - 1                    n-1                n-1
if ¬done                     1                  1
MyAlgorithm(A, n)            1                  0
return A                     1                  1
------------------------------------------------------------------
Total:                       10n-2                6n
Complexity:                  f(n) is O(n)         f(n) is Omega(n)

这也是我在stackoverflow上的第一篇文章,所以我不确定我是否正确发布了这些帖子。

1 个答案:

答案 0 :(得分:1)

看起来这个算法是冒泡排序的某种变化。假设它正常工作,它应该具有O(n^2)的性能。

要分析性能,您应该注意到过程的主体(没有递归)需要O(n),因此算法所花费的总时间为O(R n),其中R是递归在完成之前调用的次数。由于每个气泡传递应该在最终的排序位置R<=n/2至少留下一个元素,因此整个算法的结果是O(n ^ 2)。

不幸的是,在你的算法中使用递归的方式对于确定它的性能并不是特别有用:你可以很容易地用一个外部while循环来代替递归,这两个bubble循环构成了过程体的其余部分(可能是避免了你大部分的困惑......)。

递归分析有用的算法通常具有某种分而治之的结构,其中递归过程调用解决较小的子问题。这在您的算法中显然是缺乏的:递归调用总是与原始调用大小相同。