哪个更好:O(n log n)或O(n ^ 2)

时间:2014-04-27 21:29:20

标签: algorithm big-o

好的,所以我有这个项目我必须做,但我只是不明白。问题是,我有2个算法。 O(n ^ 2) O(n * log 2 n)

无论如何,我在项目信息中发现,如果 n <100 ,则 O(n ^ 2)更有效,但如果 n&gt; = 100 ,然后 O(n * log 2 n)更有效。我想用一个例子来演示使用数字和单词或绘制照片。但问题是,我不明白这一点,我也不知道如何证明这一点。

此处的任何人都可以帮助我了解这是如何运作的?

提前干杯!

编辑:谢谢大家的回复。

8 个答案:

答案 0 :(得分:54)

好问题。实际上,我总是展示这三张照片:

n = [0; 10]

enter image description here

n = [0; 100]

enter image description here

n = [0; 1000]

enter image description here

因此,O(N*log(N))远远优于O(N^2)。它更接近O(N)而非O(N^2)

但是O(N^2)算法对于N < 100在现实生活中的速度更快。有很多原因可以让它更快。可能是由于更好的内存分配或其他“非算法”效果。也许O(N*log(N))算法需要一些数据准备阶段或O(N^2)迭代更短。无论如何,Big-O表示法仅适用于足够大的Ns。

如果你想证明为什么一个算法对于小N更快,你可以测量两个算法的 1次迭代的执行时间常量开销,然后使用它们来正确的理论情节:

Example

enter image description here

或者仅测量两种算法对不同Ns的执行时间并绘制经验数据。

答案 1 :(得分:27)

如果您有疑问,请问wolframalpha

在这种情况下,它说

     n log(n)
lim --------- = 0
       n^2

或者您也可以自己计算限额:

     n log(n)        log(n)   (Hôpital)       1/n          1
lim --------- = lim --------      =     lim ------- = lim --- = 0
       n^2             n                       1           n

这意味着n^2增长得更快,因此当n log(n)足够高时,n会更小(更好)。

答案 2 :(得分:14)

Big-O表示法是asymptotic complexity的表示法。这意味着当N任意大时,它会计算复杂度。

对于小Ns,还有很多其他因素。算法可能有O(n ^ 2)循环迭代,但每次迭代都很短,而另一种算法有O(n)次迭代很长的迭代。对于大Ns,线性算法将更快。对于小Ns,二次算法会更快。

因此,对于小N,只需测量两个,看看哪个更快。无需进入渐近复杂性。

顺便说一下,不要写日志的基础。 Big-O表示法忽略常量 - O(17 * N)与O(N)相同。由于log 2 N只是ln N / ln 2,因此对数的基础只是另一个常数而被忽略。

答案 3 :(得分:7)

让我们比较一下,

一方面我们有:

n^2 = n * n

另一方面,我们有:

nlogn = n * log(n)

将它们放在一边:

n * n    versus    n * log(n)

让我们除以n这是一个常用词,得到:

n    versus    log(n)

让我们比较一下值:

n = 10           log(n) ~ 2.3
n = 100          log(n) ~ 4.6
n = 1,000        log(n) ~ 6.9
n = 10,000       log(n) ~ 9.21
n = 100,000      log(n) ~ 11.5
n = 1,000,000    log(n) ~ 13.8

所以我们有:

n >> log(n) for n > 1

n^2 >> n log(n) for n > 1

答案 4 :(得分:1)

首先,比较混合N约束的渐近复杂度是不正确的。我可以说:

  • O(n^2)O(n * log(n))慢,因为Big O notation的定义将包含n is growing infinitely

  • 对于特定的N,可以通过简单地比较N^2 * ALGORITHM_CONSTANTN * log(N) * ALGORITHM_CONSTANT来确定哪种算法更快,其中ALGORITHM_CONSTANT取决于算法。例如,如果我们遍历数组两次来完成我们的工作,渐近复杂度将是O(N)ALGORITHM_CONSTANT将是2

另外我想提一下O(N * log2N)我认为logariphm基于2(log 2 N)实​​际上与O(N * log(N))相同,因为logariphm属性。

答案 5 :(得分:1)

我们有两种比较两个Algo 的方法 - &gt;第一种方式是非常简单的比较和应用限制

T1(n)-Algo1

T2(n)=Alog2

  lim  (n->infinite) T1(n)/T2(n)=m  

(i)如果m = 0,Algo1比Algo2快

(ii)m = k两者相同

(iii)m =无限Algo2更快

*第二种方式非常简单,与第一种方式相比,你只记录两种情况,但不要忽略多次常数

             Algo 1=log n

             Algo 2=sqr(n)

             keep log n =x

             Any poly>its log


   O(sqr(n))>o(logn)

答案 6 :(得分:1)

<块引用>

无论如何,我在项目信息中发现如果 n<100,那么 O(n^2) 是 效率更高,但如果 n>=100,则 O(n*log2n) 效率更高。

让我们首先澄清当前上下文中的 Big O 表示法是什么。从 (source) 可以读到:

<块引用>

Big O 表示法是一种数学表示法,描述了极限 当参数趋向于特定时函数的行为 值或无穷大。 (..) 在计算机科学中,大 O 符号用于对算法进行分类 根据他们的运行时间或空间需求如何增长作为 输入大小增加

Big O 表示法不代表函数,而是表示具有某个渐近上限的 set of functions;可以从 source 中读到:

<块引用>

Big O 表示法根据函数的增长来表征函数 速率:具有相同增长率的不同函数可能是 使用相同的 O 符号表示。

非正式地,在计算机科学 time-complexityspace-complexity 理论中,人们可以将 Big O 表示法视为算法的分类,其中包含有关时间和空间的某些最坏情况,分别。例如,O(n)

<块引用>

如果算法的时间/空间复杂度为 O(n),则称其采用线性时间/空间或 O(n) 时间/空间。非正式地,这意味着运行时间/空间最多随输入的大小 (source) 线性增加。

O(n log n) 为:

<块引用>

对于某个正常数 k,如果 T(n) = O(n log^k n),则称算法在拟线性时间/空间中运行;线性时间/空间是 k = 1 (source) 的情况。

数学上的陈述

<块引用>

哪个更好:O(n log n) 或 O(n^2)

不准确,因为如前所述 Big O 表示法表示 set of functions。因此,更准确的应该是“O(n log n) 是否包含 O(n^2)”。尽管如此,通常这种宽松的措辞通常用于量化(对于最坏的情况)一组算法与另一组算法在输入大小增加方面的表现。比较两类算法(例如O(n log n)O(n^2))而不是

<块引用>

无论如何,我在项目信息中发现如果 n<100,那么 O(n^2) 是 效率更高,但如果 n>=100,则 O(n*log2n) 效率更高。

对于最坏的情况,您应该分析两类算法随着其输入大小( n)的增加而表现如何;当趋于无穷大时分析 n

enter image description here

正如@cem 正确指出的那样,在图像中“big-O 表示绘制函数的渐近最小上界之一,而不是指集合 O(f(n)) "

正如您在特定输入后的图像中看到的那样,O(n log n)(绿线)的增长速度比 O(n^2)(橙线)慢。这就是为什么(对于最坏的情况)O(n log n)O(n^2) 更可取,因为可以增加输入大小,并且前者的增长率比后者慢。

答案 7 :(得分:0)

我是一名数学家,所以我将尝试解释为什么 n^2 比 nlogn 快,对于 n 的小值,有一个简单的限制,而 n-->0 :

lim n^2 / nlogn = lim n / logn = 0 / -inf = 0

因此,对于 n 的小值(在这种情况下,“小值”是 [1,99] 中存在的 n),nlogn 比 n^2 快,因为我们看到 limit = 0 。 但为什么 n-->0?因为算法中的 n 可以取“大”值,所以当 n<100 时,它被认为是一个非常小的值,所以我们可以取极限 n-->0。