C 求函数时间复杂度的精确方法

C 求函数时间复杂度的精确方法,c,for-loop,time-complexity,C,For Loop,Time Complexity,如何找到此函数的时间复杂度: 代码 void f(int n) { for(int i=0; i<n; ++i) for(int j=0; j<i; ++j) for(int k=i*j; k>0; k/=2) printf("~"); } void f(int n) { 对于(int i=0;i对于i,i>0,将有i-1内环值,分别从以下位置开始计算k: i*1, i*2, ..., i(i-1)

如何找到此函数的时间复杂度:

代码

void f(int n)
{
    for(int i=0; i<n; ++i)
        for(int j=0; j<i; ++j)
            for(int k=i*j; k>0; k/=2)
               printf("~");
}
void f(int n)
{

对于(int i=0;i对于
i
i>0
,将有
i-1
内环值,分别从以下位置开始计算
k

i*1, i*2, ..., i(i-1)
由于
k
除以
2
直到它达到
0
,因此每个内部循环都需要
lg(k)
步骤。因此

lg(i*1) + lg(i*2) + ... + lg(i(i-1)) = lg(i) + lg(i) + lg(2) + ... + lg(i) + lg(i-1)
                                     = (i-1)lg(i) + lg(2) + ... + lg(i-1)
因此,总数将为

f(n) ::= sum_{i=1}^{n-1} i*lg(i) + lg(2) + ... + lg(i-1)
现在让我们从上面绑定
f(n+1)

f(n+1) <= sum_{i-1}^n i*lg(i) + (i-1)lg(i-1)
       <= 2*sum_{i-1}^n i*lg(i)
       <= C*integral_0^n x(ln x)            ; integral bound, some constant C
        = C/2(n^2(ln n) - n^2/2)            ; integral x*ln(x) = x^2/2*ln(x) - x^2/4
        = O(n^2*lg(n))

对于
i
i>0
的每个值,将有
i-1
内环的值,每个
k
值分别从以下位置开始:

i*1, i*2, ..., i(i-1)
由于
k
除以
2
直到它达到
0
,因此每个内部循环都需要
lg(k)
步骤。因此

lg(i*1) + lg(i*2) + ... + lg(i(i-1)) = lg(i) + lg(i) + lg(2) + ... + lg(i) + lg(i-1)
                                     = (i-1)lg(i) + lg(2) + ... + lg(i-1)
因此,总数将为

f(n) ::= sum_{i=1}^{n-1} i*lg(i) + lg(2) + ... + lg(i-1)
现在让我们从上面绑定
f(n+1)

f(n+1) <= sum_{i-1}^n i*lg(i) + (i-1)lg(i-1)
       <= 2*sum_{i-1}^n i*lg(i)
       <= C*integral_0^n x(ln x)            ; integral bound, some constant C
        = C/2(n^2(ln n) - n^2/2)            ; integral x*ln(x) = x^2/2*ln(x) - x^2/4
        = O(n^2*lg(n))

似乎唯一困难的部分是如何处理
k=i*j
。这可以通过意识到
log(n^2)=2log(n)
和big-O忽略常量来处理。的确,我注意到了这些事情,但正如你所说,ij部分令人困惑。最内部的循环执行log(ij)次,所以我们这里有某种总和,我似乎无法准确地表达出来,我明白。你在寻找精确的公式,比如
1+2+3+…+n=n(n+1)/2
。我不确定这段代码是否有这样一个公式,但你可以试试运气。看起来唯一困难的部分是如何处理
k=I*j
。这可以通过实现
log(n^2)=2log(n)来处理
而big-O忽略常量。确实如此,我注意到了这些事情,但问题是,正如你所说,ij部分令人困惑。最里面的循环执行log(ij)次,所以我们这里有某种总和,我似乎无法准确地表示出来,我明白。你在寻找精确的公式,比如
1+2+3+…+n=n(n+1)/2
。我不确定这段代码是否有这样的公式,但你可以试试运气。