嵌套for循环的大O:线性还是二次?

时间:2015-11-10 16:30:20

标签: algorithm big-o time-complexity nested-loops asymptotic-complexity

我试图了解如何知道算法中的嵌套for循环是否会产生线性或二次Big-Oh复杂度。以下是我提出的一些示例,但与蛮力循环和图形遍历有关。我试着

我是否正在思考正确的道路?

示例1:

N = ? // Number of elements in an array of integers
For i = 1 to N
    For j = 1 to N
        Print "foo"
  • 复杂性: O(N ^ 2)
  • 为什么?因为我们有两个嵌套for循环,它们会迭代相同的次数。因为我们在运行期间不知道N的值,那么我们不得不说复杂度是O(N ^ 2)?但是,如果我们硬编码N = 20,那么我们将有O(N)?

示例2:

N = ? // Number of elements in an array of integers
For i = 1 to log(N)
    For-each edge of log(N)
        Print "foo"
  • 复杂性: O(log(N)^ 2)
  • 为什么?因为我们有两个嵌套for循环,它们会迭代相同的log(N)次。

示例3:

V = ? // Total number of nodes in a graph
E = ? // Total number of edges in a graph (not of each iteration-node)
For i = 1 to V
    For j = 1 to E
        Print "foo"
  • 复杂性: O(V * E)
  • 为什么?因为我们不知道V = E,所以我们不能说O(V ^ 2)或O(E ^ 2)。我们不知道V> = E还是V <= E。所以我们只说O(V * E)来涵盖所有情况。

示例4:

V = ? // Total number of nodes in a graph
For i = 1 to V
    For-each edge of V[i]
        Print "foo"
  • 复杂性: O(| V | + |图中的边|)
  • 为什么?因为我们知道|图中的边| != | V |,因此迭代次数不成比例。当图表是指向与未指示时,这是否重要?

1 个答案:

答案 0 :(得分:1)

Big-O表示法描述算法的运行时间如何随输入的大小而变化。

使用示例1,如果将N硬编码为20,则输入没有缩放。该算法实际上变为O(1)

示例2类似于您对示例1的直觉,除了每个循环仅运行log(n)次迭代。

在示例3中,我将其描述为在O(mn)时间内运行(m =边数,n =顶点数),而不是O(n^2)

最后一个例子实际上比我第一次给它一点点细微差别(谢谢,@ Harkyl!)。

边缘由顶点分隔,因此除了运行外循环2|E|次之外,有效地运行内循环总共|V|次。这导致您的算法复杂度为O(|V| + 2|E|)。常量通常在big-o表示法中被忽略,因此这被认为与O(|V| + |E|)相同。