我更喜欢尽可能少的正式定义和简单的数学。
当前回答
它切断到骨头,只提供关于算法的规模性质的信息,具体如何使用资源(思考时间或记忆)的算法规模,以回应“输入大小”。
考虑蒸汽发动机和火箭之间的差异. 它们不仅仅是相同的东西的不同品种(如说,一个Prius发动机与一个Lamborghini发动机),但它们是显著不同的类型的驱动系统,在它们的核心。
其他回答
如果我想向6岁的孩子解释这一点,我会开始绘制一些函数f(x) = x 和f(x) = x^2 例如,并问一个孩子哪个函数将是页面顶部的顶部函数。
大 O 是算法使用时间/空间的尺寸,与其输入的尺寸相比。
如果一个算法是O(n),那么时间/空间将与其输入相同的速度增加。
如果一个算法是O(n2)则时间/空间增加以其输入的速度为方形。
等等等。
这是一个非常简单的解释,但我希望它涵盖了最重要的细节。
让我们说你的算法处理问题取决于某些“因素”,例如,让我们做它N和X。
根据 N 和 X,您的算法将需要一些操作,例如在 WORST 案例中,它是 3(N^2) + log(X) 操作。
由于Big-O不太关心恒定的因素(aka 3),你的算法的Big-O是O(N^2 + log(X))。它基本上翻译“你的算法需要最糟糕的案例规模的操作数量”。
大 O 描述了一个功能的增长行为上限,例如一个程序的运行时间,当输入变得大。
例子:
O(n):如果我翻倍输入大小,运行时间将翻倍O(n2):如果输入大小将翻倍运行时间四倍O(log n):如果输入大小翻倍运行时间将增加一倍O(2n):如果输入大小增加一倍,运行时间将翻倍
输入尺寸通常是比特所需的空间来代表输入。
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