我一直在努力探索这种特殊的复杂性计算,但我读到的关于这种复杂性的一切都告诉我它是大型O(2 ^ n)类型,但是如果我在代码中添加一个计数器,检查每给定n迭代的次数,它似乎遵循4 ^ n的曲线。也许我只是误解了,因为我放了一个计数++;在范围内。
这不是大O型(2 ^ n)吗?
public int test(int n)
{
if (n == 0)
return 0;
else
return test(n-1) + test(n-1);
}
我将不胜感激任何提示或解释!我对这种复杂性计算完全不熟悉,而且这个让我偏离了轨道。
//此致
答案 0 :(得分:4)
int test(int n)
{
printf("%d\n", n);
if (n == 0) {
return 0;
}
else {
return test(n - 1) + test(n - 1);
}
}
在函数顶部打印输出,运行test(8)
并计算每个n
打印的次数,得到此输出,清楚地显示2 n 成长。
$ ./test | sort | uniq -c
256 0
128 1
64 2
32 3
16 4
8 5
4 6
2 7
1 8
(uniq -c
计算每行发生的次数。0
打印256次,1
128次,等等。)
也许你的意思是你得到了O(2 n +1 )的结果,而不是O(4 n < / SUP>)?如果你把所有这些数字相加,你会得到511,其中 n = 8是2 n +1 -1。
如果这就是你的意思,那就没关系。 O(2
答案 1 :(得分:1)
设x(n)为test
的总调用次数。
x(0) = 1
x(n) = 2 * x(n - 1) = 2 * 2 * x(n-2) = 2 * 2 * ... * 2
共有n两个 - 因此有2 ^ n个电话。
答案 2 :(得分:1)
首先关闭:'else'语句已过时,因为如果if已经计算为true则返回。
关于主题:每次迭代分叉2次不同的迭代,分叉2次迭代本身等等。因此,对于n = 1,函数被调用2次,加上始发调用。对于n = 2,它被称为4 + 1次,然后是8 + 1,然后是16 + 1等。因此,复杂度显然是2 ^ n,因为常数被指数抵消。
我怀疑你的计数器在两次通话之间没有正确重置。
答案 3 :(得分:1)
此函数的复杂度T(n)
可以很容易地显示为等于c + 2*T(n-1)
。
T(0) = 0
T(n) = c + 2*T(n-1)
有解决方案c *(2 ^ n - 1),或类似的东西。它是O(2 ^ n)。
现在,如果你将函数的输入大小设置为m = lg n
,在这种情况下可以接受(表示n
的位数,真正的输入大小)那么这是实际上是一个O(m^4)
算法......因为O(n ^ 2)= O(m ^ 4)。