我一直在尝试计算以下函数的复杂性:
k=n;
while(k>0)
g(n);
k=k/2; {Comment: this is integer division, so 1/2=0}
end while;
for(j=0;j<m;j++)
f(m);
具体来说,while循环的复杂性。我被告知g(n)的复杂性是O(n),但我不确定它的复杂性是什么,以及我将如何解决它。我已经意识到复杂性不会是O(0.5n ^ 2),但我不确定如何计算它,因为每次都减半。有人有什么想法吗?
答案 0 :(得分:4)
如果g(n)是O(n),那么你的复杂度是O(n * log(n))
为了进一步解释,我们暂时忽略g(n)
k = n;
while(k > 0) {
k = k / 2;
}
假设n = 1000
然后我们将获得以下k值
Pass | k
-------------
0 | 1000
1 | 500
2 | 250
3 | 125
4 | 62
5 | 31
6 | 15
7 | 7
8 | 3
9 | 1
10 | 0 (stopped)
log(1000)= 9.96 请注意,只需要10次迭代就可以将k降为零。 这是log(n)计算复杂性的一个例子。
然后当你在循环中添加g(n)时,这意味着你为每次迭代添加O(n),这给了我们总的O(n * log(n))
答案 1 :(得分:2)
while循环的复杂性显然是O(n log n)
。有log n
次迭代,因为在每次迭代结束时k
除以2.要获得迭代次数,请将n
表示为2的幂,比如2 ^ x。如果2^x=n, then x = log n
。这就是while循环的复杂性为O(n log n)
的原因。不要感到困惑,因为n
不具有2的幂,这意味着log n
并不总是一个整数,你应该写,而不是log n,[log n]
,其中[y]
是y
的整数部分。您始终可以将[log n]
表示为c* log n
,其中c是常量,这不会改变算法的复杂性。因此,您不需要[]
功能,O(n log n)
是可接受且正确的答案。
for循环的复杂性取决于f(m)
的复杂性。如果O(f(m))为O(1)
,则循环为O(m),但如果O(f(m))
为O(m)
,则循环为O(m^2)
。因为f(m)
也是算法的一部分,如果你想确定整个代码的复杂性,你需要知道f(
的复杂性。
答案 2 :(得分:0)
算法的复杂性是:
你的第一个循环运行O(logn)次,每次迭代必须执行g(n)。因此需要
O(sum{i from 0 to log(n)}{O(g(i))}).
第二个循环运行m次。需要:
O(sum{j from 0 to m}{O(f(i))})
算法的总复杂性为:
O(sum{i from 0 to log(n)}{O(g(i))}) + O(sum{j from 0 to m}{O(f(i))})