【问题标题】:O(v + e) Time Complexity Breadth First SearchO(v + e) 时间复杂度广度优先搜索
【发布时间】:2021-06-24 15:24:18
【问题描述】:

我在这里查看了其他答案,但所有内容要么写得乱七八糟,要么代码的运行方式与我的不同。我正在寻找的是一个非常清晰的解释,说明为什么下面描述的这种广度优先搜索的时间复杂度是 O(v + e)。

class Node {
  constructor(name) {
    this.name = name;
    this.children = [];
  }

  breadthFirstSearch() {
    const array = []
    const queue = [this]
        
        while(queue.length) {
            const node = queue.shift()
            array.push(node.name)
            queue.push(...node.children)
        }
        
        return array
  }
}

下面的每个顶点都是上面描述的每个节点类。你可以想象breadthFirstSearch方法被“A”节点调用。

           A
        /  |  \
       B   C   D
      / \     / \
     E   F   G   H
        / \
       I   J

我理解 O(v) 部分,因为很清楚我们访问了每个节点。 O(e) 部分是我无法绕开的部分。提前致谢。

【问题讨论】:

  • 您是否对在树上进行 BFS 的情况特别感兴趣?或者这是关于一般的图表?
  • 只是您在此处看到的树的类型。大部分平衡的简单树。

标签: tree computer-science breadth-first-search traversal


【解决方案1】:

不是 e = v-1,因为每个顶点都连接到除根之外的 1 个父节点吗?如果是这样的话,那么e这个词就是迂腐了,可以改写为O(v)。

如果您查看广度优先搜索 (https://en.wikipedia.org/wiki/Breadth-first_search) 的维基百科页面,它给出的时间复杂度为 O(|V| + |E|) 对于一般图,其中边数 |E|如果每对顶点都由一条边连接,则可以高达 |V|^2。在最坏的情况下,BFS 必须检查每个边缘。树是边数为 |V|-1 的图的一种特殊情况。

【讨论】:

  • 我真的不确定,这件事让我很困惑。
【解决方案2】:

在一般图上运行广度优先搜索的时间复杂度为 O(v + e),其中同一对节点之间可能存在循环和多条路径。您可能经常看到的复杂论点主要是为了证明加法“+ e”项而不是 v 项的合理性。

在树上运行 BFS 的情况下,运行时间是 O(v)。有几种方法可以看到这一点:

  1. 树中的每个节点最多被触摸两次:第一次是在处理其父节点时将其推入队列,第二次是在其自身从队列中取出并处理其子节点时。这意味着完成的工作与树中的节点数成正比,这就是 O(v) 项的来源。
  2. 如果您忽略将子项推入队列的成本,那么循环显然将在树中的每个节点最多运行一次,因为节点最多只能入队一次。这给了我们一个 O(v) 的基线工作量,忽略了推送成本。所以我们必须解决的部分是完成所有推送到队列中需要多少工作。每个节点最多可以推送一次,因此在外循环的所有迭代中,推送的总工作量为 O(v),因此完成的总工作量为 O(v)。
  3. 如果您相信在具有 v 个节点和 e 个边的一般图中,广度优先搜索的成本是 O(v + e),那么在树上进行 BFS 的成本必须是 O(v),因为在一棵树,我们有 e = v - 1 的规则。一种看待这一点的方法:除根以外的每个节点都有一条边进入它。

【讨论】:

    【解决方案3】:

    如果图是一棵树,那么 O(?) = O(?+?),就像在树中我们有等式 ? = ?−1。

    如果图是连通并且有循环(即它的边比它的生成树多),那么BFS是O(?)。这是因为每条边都必须被访问(即使只是意识到它连接到一个已经访问过的节点)。

    如果图可能是不连通的,即多个连通组件的集合,那么节点可能比边多,我们知道 BFS 将不得不访问 all 个节点,所以 O(?) 不会覆盖它,而是 O(?)。

    为了涵盖所有这些可能性,我们必须说 O(?+?) 或 O(max(?,?)),这是相同的复杂性。但是如果你只对树感兴趣,你也可以说 O(?) 或 O(?),因为它们都是等价的。

    【讨论】:

      猜你喜欢
      • 2019-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 2016-07-28
      • 2011-01-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多