我真的不知道“Big-O”是什么以及如何在实践中使用它,所以我希望有人能给我一个简单的解释,也许还有一些Java编程示例。
我有以下问题:
这些术语的含义是什么(尽可能简单)以及它们在java中如何使用: BigO(1)、BigO(n)、BigO(n2) 和 BigO(log(n)) ?
如何根据现有的 Java 代码计算 Big-O?
如何使用Big-O排序
如何使用Big-O递归
希望有人能帮忙。
Big O 用于说明算法随着输入大小的增加而扩展的速度
O(1)意味着随着输入大小的增加,运行时间不会改变
O(n) 意味着随着输入大小加倍,运行时间或多或少会加倍
O(n^2) 意味着当输入大小加倍时,运行时间将增加或减少四倍
O(f(n)) 意味着随着输入大小加倍,运行时间将增加到 f(2n) 左右
关于 Big-O、排序和递归。
Big-O 排序并不是真正的算法。不过,您可以使用 Big O 来告诉您排序算法的速度有多快。
为了计算递归函数的 Big-O,我建议使用 主定理。
确定大O的指南:
通常,您需要确定输入大小(例如数组长度或链表中的节点数等)
然后问问自己,如果你的输入大小加倍会发生什么?还是三倍? 如果您有一个遍历每个元素的 for 循环:
//say array a has n elements
for (int i = 0; i < n; i++) {
// do stuff
a[i] = 3;
}
然后将 n 加倍将使循环运行时间加倍,因此时间复杂度为 O(n)。将 n 增加三倍将使所需时间增加三倍,因此代码随输入大小线性缩放。
如果您有一个 2D 数组并嵌套 for 循环:
// we say that each dimension of the array is upper bounded by n,
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
// do stuff
a[i][j] = 7;
}
}
当 n 加倍时,代码将花费 2^2 = 4 倍的时间。如果输入大小增加三倍,代码将花费 3^2 = 9 倍的时间。所以大 O 是 O(n^2)。
Big-O 表示法是一种用于在输入非常大时显示计算机算法性能的表示法。
三个快速编程示例,使用 Java:
O(1):
for (int i=0; i<3; i++) {
System.out.println(i);
}
O(n):
int n = 1000000; /* Some arbitrary large number */
for (int i=0; i<n; i++) {
System.out.println(i);
}
O(n2):
int n = 1000000; /* Some arbitrary large number */
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
System.out.println(i * j);
}
}
大 O(它是字母 O - 大,而不是小字母 o)给出了当输入大小 (n) 变化时算法如何缩放的想法。数字是
例如,如果 n 从 100 项加倍到 200 项,
等等。
注意log(n)可以理解为“n中位的个数”。这意味着,如果您从具有两位数的 n(例如 99)到具有双位数的 n(例如 9999 的四位数字),则运行时间只会增加一倍。当您将数据分成两堆并分别求解并将解决方案合并回去时(例如在排序时),通常会发生这种情况。
通常输入数据的每个循环都会乘以 n。因此,单个循环的复杂度为 O(n),但如果您需要将每个元素与其他每个元素进行比较,则会得到 O(n^2),依此类推。请注意,时间是相对的,因此对于较小的 n 值,快速 O(n^2) 算法可能会优于慢速 O(n) 算法。
另请注意,O 是“最坏情况”。因此,通常运行速度快的快速排序仍然是 O(^2),因为有可悲的输入数据导致它将每个元素进行比较。 这很有趣,因为大多数算法对于小型数据集来说速度很快,但是您需要知道它们如何处理可能大数千或数百万倍的输入数据,如果您有 O(n^2) 或 O(n^),这一点很重要3)或更糟。这些数字是相对的,因此如果给定的算法是慢还是快,它不会说明任何 bps,只是当您将输入大小加倍时最坏的情况是什么样子。