概述
其他人给出了很好的图表示例,例如树形图。我没有看到任何简单的代码示例。所以除了我的解释之外,我会提供一些带有简单打印语句的算法来说明不同算法类别的复杂性。
首先,您需要对对数有一个大致的了解,可以从https://en.wikipedia.org/wiki/Logarithm获得。自然科学使用e
和自然日志。工程弟子会使用 log_10(以 10 为底的对数),而计算机科学家将大量使用 log_2(以 2 为底的对数),因为计算机是基于二进制的。有时你会看到 natural log as 的缩写ln()
,工程师通常将 _10 关闭而只使用log()
log_2 缩写为lg()
。所有类型的对数都以相似的方式增长,这就是它们共享相同类别的原因log(n)
。
当您查看下面的代码示例时,我建议您查看 O(1),然后是 O(n),然后是 O(n^2)。在你对这些很好之后,再看看其他的。我已经包含了干净的示例和变体,以展示细微的变化仍然可以导致相同的分类。
您可以将 O(1)、O(n)、O(logn) 等视为增长的类别或类别。有些类别比其他类别需要更多时间。这些类别有助于为我们提供一种排序算法性能的方法。随着输入 n 的增长,一些增长得更快。下表以数字方式说明了所述增长。在下表中,将 log(n) 视为 log_2 的上限。
各种大 O 类别的简单代码示例:
O(1) - 恒定时间示例:
算法 1 打印 hello 一次,它不依赖于 n,所以它总是在恒定时间内运行,所以它是O(1)
.
print "hello";
算法 2 打印 hello 3 次,但它不依赖于输入大小。即使随着 n 的增长,这个算法也只会打印 hello 3 次。话虽如此 3, 是一个常数,所以这个算法也是O(1)
.
print "hello";
print "hello";
print "hello";
O(log(n)) - 对数示例:
算法 3 演示了在 log_2(n) 中运行的算法。请注意 for 循环的后操作将 i 的当前值乘以 2,因此i
从 1 到 2 到 4 到 8 到 16 到 32 ...
for(int i = 1; i <= n; i = i * 2)
print "hello";
算法 4 演示了 log_3。通知i
从 1 到 3 到 9 到 27...
for(int i = 1; i <= n; i = i * 3)
print "hello";
算法 5 很重要,因为它有助于表明,只要数字大于 1 并且结果与自身重复相乘,就表明您正在查看对数算法。
for(double i = 1; i < n; i = i * 1.02)
print "hello";
O(n) - 线性时间示例:
这个算法很简单,打印 hello n 次。
for(int i = 0; i < n; i++)
print "hello";
该算法显示了一个变体,它将打印 hello n/2 次。n/2 = 1/2 * n。我们忽略 1/2 常数,看到这个算法是 O(n)。
for(int i = 0; i < n; i = i + 2)
print "hello";
O(n*log(n)) - nlog(n) 示例:
将此视为 和 的O(log(n))
组合O(n)
。for 循环的嵌套帮助我们获得O(n*log(n))
for(int i = 0; i < n; i++)
for(int j = 1; j < n; j = j * 2)
print "hello";
算法 9 类似于算法 8,但每个循环都允许变化,这仍然导致最终结果为O(n*log(n))
for(int i = 0; i < n; i = i + 2)
for(int j = 1; j < n; j = j * 3)
print "hello";
O(n^2) - n 平方示例:
O(n^2)
通过嵌套标准 for 循环很容易获得。
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
print "hello";
与算法 10 类似,但有一些变化。
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j = j + 2)
print "hello";
O(n^3) - n 立方示例:
这类似于算法 10,但使用 3 个循环而不是 2 个循环。
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
for(int k = 0; k < n; k++)
print "hello";
与算法 12 类似,但有一些变化仍会产生O(n^3)
.
for(int i = 0; i < n; i++)
for(int j = 0; j < n + 5; j = j + 2)
for(int k = 0; k < n; k = k + 3)
print "hello";
概括
上面给出了几个直接的例子和变化,以帮助演示可以引入哪些细微的变化,而这些变化实际上不会改变分析。希望它能给你足够的洞察力。