Big O代码片段

时间:2010-09-08 15:29:16

标签: big-o

你好,我曾经使用Big O表示法犯罪,所以我有点生气。

我知道有一个循环,循环n次是O(n),并且有一个循环在另一个循环n次的循环中循环n次是O(n ^ 2)。

但是在下面的代码片段中,我有一个循环n次循环,并且在循环中循环n次i。

此代码的最差和最佳O符号是什么?

最糟糕的是它在没有发现碰撞的情况下运行,最好的情况是在2个第一个矩形之间发生碰撞。

class TestClass
{
    bool Run(List<Rectangle> R)
    {
        var b = false;
        var i = 0;
        var n = R.Count;
        var j = 0;
        while ((i < n-1 ) && !b )
        {
            j = i + 1;
            while (j<n && !b)
            {
                if ((R[i].x >= R[j].x - R[i].w) && (R[i].x <= R[j].x + R[j].w))
                    if ((R[i].y <= R[j].y + R[i].h) && (R[i].y >= R[j].y - R[j].h))
                        b = true;
                j++;
            }
            i++;
        }

        return b;
    }
}

public class Rectangle
{
    public int x;
    public int y;
    public int w;
    public int h;
}

2 个答案:

答案 0 :(得分:3)

正如一位评论者所指出的,Big-O始终是最糟糕的情况,所以如果增加R.Count的值会使你的最坏情况增加的速度大于n * log(n) ,你进入了n²的领域。

由于你有一个双嵌套while循环,没有额外的方法调用,所以我一眼就知道它是O(n²)。

但是,在这种情况下,由于i和j从不递增,并且n从不递减,并且您的循环都基于i或j小于n,因此该函数将向右退出离开(基于你的if陈述),或永远不会。

O(infinity)?

修改

好的,现在你增加它们,每次运行时n *(ni)位基本上平均为n *(n / 2)(不是所有运行的平均,但是而是每个运行的平均值。这是因为当你穿过外环时,你将会做(n,n-1,n-2,...,3,2,1)内环。如果您将此设置折叠起来,则可以轻松总结循环次数:

n + 1 == n + 1
(n-1) + 2 == n + 1
(n-2) + 3 == n + 1
...

所以你最终得到n + 2个n + 1个实例,它出现在(n²+ n)/ 2。从大O角度来看,这与n²相同。

答案 1 :(得分:1)

您的实际最差情况下的运行时间是n X n / 2 =n²/ 2。抛弃常数,它是O(n²)