【问题标题】:What is the time complexity of this loop?这个循环的时间复杂度是多少?
【发布时间】:2015-06-17 19:35:15
【问题描述】:

如何确定这个循环的时间复杂度:

for(int i = N-1; i >= 0; i--)
{
    for(int j = 1; j <= i; j++)
    {
        if(numbers[j-1] > numbers[j])
        {
            temp = numbers[j-1];
            numbers[j-1] = numbers[j];
            numbers[j] = temp;
        }
    }
}

您可能已经注意到,这是冒泡排序算法。还有这个算法的比较和赋值的频率计数是一样的吗?

【问题讨论】:

  • “频率计数”是什么意思?
  • 你的意思是时间复杂度,“大 O”时间?
  • 是的,我的意思是时间复杂度,我不知道具体叫什么,但我想找到更具体的答案。

标签: algorithm time-complexity


【解决方案1】:

计算复杂度

您需要添加正在执行的基本操作/机器指令。 (作为输入大小的函数)

计算

for(int i = N-1; i >= 0; i--)
{          |        |     |
           c1       c2    c3
   for(int j = 1; j <= i; j++)
   {       |        |     |
           c4       c5    c6
      if(numbers[j-1] > numbers[j])--c7
      {
         temp = numbers[j-1];
         numbers[j-1] = numbers[j];
         numbers[j] = temp;
      }
   }
}

c1,c2,c3,c4,c5,c6,c7 是执行与这些结构相对应的机器指令的成本(如 i>=0,j

Now for i=N-1 the innerloop is executed N-1 times
    for i=N-2 the innerloop is executed N-2 times
    ....

    for i=0 the innerloop is executed 0 times

所以内部循环执行(N-1)+(N-2)+...1+0 次,即 = N*(N-1)/2

Look carefully the cost is
 = c1+ c2*(N+1) + c3*N+ c4*N+((N*(N-1)/2)+1)*(c5)+ (N(N-1)/2)*(c6+c7);
 = c1+c2+c5+ N*(c2+c3-(c5+c6+c7)/2) + N^2 * (c5/2 + c6/2 + c7/2)
 = c8 + N*c9 + N^2 *(c10)   [c8,c9,c10 are constants]

为什么我们将 N+1 与 c2 相乘?那是因为最后一次检查实际上是i=-1

现在对于较大的 N 值,N^2 支配 N。 所以时间复杂度是O(N^2)。 所以,T(N)=O(N^2)

【讨论】:

  • 为什么 c4 == c4*N 而不是 c4*(N*(N-1)/2) 的成本? c4执行的次数不是和内循环一样多吗?
  • @Justin.:这就是 for 循环的工作原理——我们为循环索引变量初始化一次——而不是循环执行的每次迭代。这就是为什么c4*N
【解决方案2】:

当前实现的复杂度在最佳和最坏情况下都是 O(n^2),如果只计算比较、只计算分配或两者都计算,则相同。

这是详细的计算,K 是一个常数,具体取决于您要考虑哪些操作来考虑时间复杂度:

如果您想要更高效的冒泡排序算法,请查看Wiki pagethis answer 上的伪代码,您会发现最佳情况复杂度为 O(n) 的算法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多