您好我需要帮助找到此算法的复杂性。 您能否逐行回答复杂性,而不仅仅是最终结果?
算法如下:
int algorithm(int x)
{
int y = 1;
while (y <= x-1)
{
int z = y*2;
while (z <= x)
{
int w = 1;
while (w <= z)
{
w++;
}
z++;
}
y++;
}
}
任何帮助将不胜感激!
由于
答案 0 :(得分:2)
int algorithm(int x)
{
int y = 1;
while (y <= x-1) // <<< loop 1
{
int z = y*2;
while (z <= x) // <<< loop 2
int w = 1;
while (w <= z) // <<< loop 3
{
w++;
}
z++;
}
y++;
}
}
让我们把它分解。
循环1:你绕过(x-1)次:我们称之为O(x)。容易。
循环2:我们以2*y
开始Z,所以2, 4, 6, ...
从那里开始直到x
。让我们把它们加起来:
sum((x-2) + (x-4) + (x-6) + ... + (x - x)) =
x * x / 2 - 2 * (1+2+3+...+x/2) =
x * x / 2 - 2 * (x/2)*(x/2+1) / 2 ~
x * x / 2 - x * x / 4 =
x * x / 4
= O(x^2)
现在是最里面的循环:从w = 1
到w = z
;所以它循环z
次。我们知道
z = 2, 4, 6, ... x
所以最里面的循环增加了x
(x / 2 ......同样的东西)的顺序。
将循环3的O(x)与循环2的O(x ^ 2)(包括第一循环的影响)相结合,我们得出结论“算法”的顺序为x ^ 3。要验证,我们可以修改您的代码:
#include <stdio.h>
int algorithm(int x)
{
int c = 0;
int y = 1;
while (y <= x-1)
{
int z = y*2;
while (z <= x)
{
int w = 1;
while (w <= z)
{
c++; // count complexity
w++;
}
z++;
}
y++;
}
return c;
}
int main(void) {
int ii;
for(ii = 200; ii <= 400; ii+=10) {
printf("%d %d\n", ii, algorithm(ii));
}
}
输出结果为:
200 1338350
210 1549030
220 1780735
230 2034465
240 2311220
250 2612000
260 2937805
270 3289635
280 3668490
290 4075370
300 4511275
310 4977205
320 5474160
330 6003140
340 6565145
350 7161175
360 7792230
370 8459310
380 9163415
390 9905545
400 10686700
在lin-log图上绘制这个图,你会得到一条相当直线。
当你取algorithm(400) / algorithm(300)
的比率时,得到2.369。当你(400/300)^3
时,答案是2.370
。我认为这足以让人信服。
答案 1 :(得分:0)
按照以下正式步骤(我希望您对Sigma Notation感到满意),您将能够获得算法的确切增长顺序: