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


当前回答

大 O 描述了一个功能的增长行为上限,例如一个程序的运行时间,当输入变得大。

例子:

O(n):如果我翻倍输入大小,运行时间将翻倍O(n2):如果输入大小将翻倍运行时间四倍O(log n):如果输入大小翻倍运行时间将增加一倍O(2n):如果输入大小增加一倍,运行时间将翻倍

输入尺寸通常是比特所需的空间来代表输入。

其他回答

要做一个字面类似,你不关心跑者能跑到100米,甚至跑到5K的速度,你更关心马拉松人,最好是超级马拉松人(除此之外,跑的类似性会崩溃,你必须转向“长跑”的形象意义)。

关于所有这些数学逻辑和多元化是什么? 显然算法与这些数学术语内在相关。 如果你测量区块上的所有孩子的高度,它会花费你那么多时间,因为有孩子。 这是内在相关的 n^1 或只是 n 的概念,在那里 n 是区块上的孩子数量。

我希望我已经解释说,大O的评级仅仅是关于长期,数学与计算方式有内在的联系,数学术语和其他简化与长期有相当常见的联系。

大 O 评分是描述一个算法的空间或运行时间的上限的一种方式. n 是问题的元素数量(即序列的尺寸,树上的节点数量等) 我们有兴趣描述运行时间,因为 n 变得大。

要说二进制搜索有运行时间的O(登录)是说有某些恒定的c,你可以增加登录(n)通过它将总是比运行时间的二进制搜索。

换句话说,g(n)是你的算法的运行时间,我们说g(n) = O(f(n))当g(n) <=c*f(n)当n > k,当c和k是某些恒定的。

如果我想向6岁的孩子解释这一点,我会开始绘制一些函数f(x) = x 和f(x) = x^2 例如,并问一个孩子哪个函数将是页面顶部的顶部函数。

大 O 评分最常被编程者用作计算(算法)将需要多长时间完成的约定测量,表达为输入组的尺寸的函数。

在许多情况下,一个算法的“O”将落入下列情况之一:

O(1) - 完成时间是相同的,无论输入组的尺寸. 一个例子是通过指数访问一个序列元素. O(Log N) - 完成时间增加大约与 log2(n)相匹配。 例如, 1024 个元素需要大约两倍的长度为 32 个元素,因为 Log2(1024) = 10 和 Log2(32) = 5. 一个例子是找到一个元素在二进制搜索树(BST)。

大 O 忽略了没有有意义的因素,因为输入尺寸向无限增加,而函数的增长曲线,这意味着由函数添加或加倍的恒数只是被忽略。


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