我更喜欢尽可能少的正式定义和简单的数学。


当前回答

测量软件程序的速度非常困难,当我们尝试时,答案可以非常复杂,并且充满了例外和特殊案例,这是一个很大的问题,因为所有这些例外和特殊案例都令人沮丧和无助,当我们想比较两个不同的程序,以确定哪个是“最快”。

好事:

邪恶的:

和那可怕的:

其他回答

我不确定我正在进一步贡献这个主题,但我仍然认为我会分享:我曾经发现这个博客帖子有几个非常有用的(也许非常基本的)解释和例子关于Big O:

通过例子,这有助于在我的<unk>子像<unk>子一样的喉<unk>中获得细微的基本,所以我认为这是一个相当下载10分钟的阅读,让你走在正确的方向。


actualAlgorithmTime(N) ∈ O(bound(N))
                                       e.g. "time to mergesort N elements 
                                             is O(N log(N))"

actualAlgorithmTime(N)                 e.g. "mergesort_duration(N)       "
────────────────────── < constant            ───────────────────── < 2.5 
       bound(N)                                    N log(N)         



#handshakes(N)
────────────── ≈ 1/2
     N²

    N²/2 - N/2         (N²)/2   N/2         1/2
lim ────────── = lim ( ────── - ─── ) = lim ─── = 1/2
N→∞     N²       N→∞     N²     N²      N→∞  1
                               ┕━━━┙
             this is 0 in the limit of N→∞:
             graph it, or plug in a really large number for N


这让我们做出这样的陈述......

我把时间的倍增到一个O(N)(“线性时间”)算法所需要的时间。


某些无形上级的算法(例如,非比较的O(N log(N))类型)可能具有如此大的恒定的因素(例如,100000*N log(N))),或相对较大的顶部,如O(N log(N))与隐藏的+100*N,它们很少值得使用,即使在“大数据”。



for(i=0; i<A; i++)        // A * ...
    some O(1) operation     // 1

--> A*1 --> O(A) time

visualization:

|<------ A ------->|
1 2 3 4 5 x x ... x

other languages, multiplying orders of growth:
  javascript, O(A) time and space
    someListOfSizeA.map((x,i) => [x,i])               
  python, O(rows*cols) time and space
    [[r*c for c in range(cols)] for r in range(rows)]

for every x in listOfSizeA:   // A * (...
    some O(1) operation         // 1
    some O(B) operation         // B
    for every y in listOfSizeC: // C * (...
        some O(1) operation       // 1))

--> O(A*(1 + B + C))
    O(A*(B+C))        (1 is dwarfed)

visualization:

|<------ A ------->|
1 x x x x x x ... x

2 x x x x x x ... x ^
3 x x x x x x ... x |
4 x x x x x x ... x |
5 x x x x x x ... x B  <-- A*B
x x x x x x x ... x |
................... |
x x x x x x x ... x v

x x x x x x x ... x ^
x x x x x x x ... x |
x x x x x x x ... x |
x x x x x x x ... x C  <-- A*C
x x x x x x x ... x |
................... |
x x x x x x x ... x v

例子3:

function nSquaredFunction(n) {
    total = 0
    for i in 1..n:        // N *
        for j in 1..n:      // N *
            total += i*k      // 1
    return total
}
// O(n^2)

function nCubedFunction(a) {
    for i in 1..n:                // A *
        print(nSquaredFunction(a))  // A^2
}
// O(a^3)

如果我们做一些有点复杂的事情,你可能仍然能够视觉地想象正在发生的事情:

for x in range(A):
    for y in range(1..x):
        simpleOperation(x*y)

x x x x x x x x x x |
x x x x x x x x x   |
x x x x x x x x     |
x x x x x x x       |
x x x x x x         |
x x x x x           |
x x x x             |
x x x               |
x x                 |
x___________________|

<----------------------------- N ----------------------------->
x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x
x x x x x x x x x x x x x x x x
x x x x x x x x
x x x x
x x
x

<----------------------------- N ----------------------------->
x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x
x x x x x x x x x x x x x x x x|x x x x x x x x|x x x x|x x|x

   <----------------------------- N ----------------------------->
 ^  x x x x x x x x x x x x x x x x|x x x x x x x x x x x x x x x x
 |  x x x x x x x x|x x x x x x x x|x x x x x x x x|x x x x x x x x
lgN x x x x|x x x x|x x x x|x x x x|x x x x|x x x x|x x x x|x x x x
 |  x x|x x|x x|x x|x x|x x|x x|x x|x x|x x|x x|x x|x x|x x|x x|x x
 v  x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x

[myDictionary.has(x) for x in listOfSizeA]
 \----- O(1) ------/    

--> A*1 --> O(A)


混合和中型案例复杂性

(请参见中间案例和折扣分析之间的差异,如果您对此主题感兴趣。




数学 Addenda

这里来了大O,告诉我们这个数学是多么艰难。

现在他们要求我添加一个到十个!为什么我会这样做?我不想添加一个到六个?添加一个到十个......好......这会更难!

对于大 n 而言, n 平方比 n 更大。

一个:我选择一张卡在我们现在工作的地板部分,你可以为我选择一个,如果你愿意(第一次我们这样做,“我们现在工作的地板部分”是整个地板,当然。

大 O 告诉我们:这个类型需要 O(n log n) 工作完成,在中间情况下。

现在你知道我的朋友,大O,他帮助我们做不到工作,如果你知道大O,你也可以做不到工作!

你和我一起学到了这一切!你太聪明了!谢谢你!

现在这个工作已经完成了,让我们玩吧!


EDIT:快注,这几乎是令人困惑的Big O评分(这是一个上线)与Theta评分(这是一个上线和下线)。在我的经验中,这实际上是非学术设置讨论的典型。

在一个句子中:随着你的工作的规模上升,完成工作需要多长时间?

“大O”评分的一个重要方面是,它不会说哪个算法会更快到一个特定的尺寸。 采取一个字符串(字符串,整体值)对一系列对(字符串,整体值)。 是否更快地找到字符串中的关键或字符串中的元素,基于字符串? (即字符串, “找到字符串部分与特定的关键相匹配的第一个元素” ) 字符串是基因。

一个简单的答案可以是:

大 O 代表了这个算法可能最糟糕的时间/空间. 算法永远不会超过这个限制的空间/时间. 大 O 代表了极端情况下的时间/空间复杂性。