我在查找递归方法的复杂性方面遇到了麻烦。我有一个算法,按升序对数组元素进行排序。基本上我所做的是写下算法中的每一步以及最佳/最差情况下的执行次数,然后取每个案例的总和并找到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上的第一篇文章,所以我不确定我是否正确发布了这些帖子。
答案 0 :(得分:1)
看起来这个算法是冒泡排序的某种变化。假设它正常工作,它应该具有O(n^2)
的性能。
要分析性能,您应该注意到过程的主体(没有递归)需要O(n)
,因此算法所花费的总时间为O(R n)
,其中R
是递归在完成之前调用的次数。由于每个气泡传递应该在最终的排序位置R<=n/2
至少留下一个元素,因此整个算法的结果是O(n ^ 2)。
不幸的是,在你的算法中使用递归的方式对于确定它的性能并不是特别有用:你可以很容易地用一个外部while循环来代替递归,这两个bubble循环构成了过程体的其余部分(可能是避免了你大部分的困惑......)。
递归分析有用的算法通常具有某种分而治之的结构,其中递归过程调用解决较小的子问题。这在您的算法中显然是缺乏的:递归调用总是与原始调用大小相同。