【问题标题】:Time complexity of adjacency list representation?邻接表表示的时间复杂度?
【发布时间】:2017-07-08 06:56:18
【问题描述】:

我正在通过此链接进行邻接列表表示。

http://www.geeksforgeeks.org/graph-and-its-representations/

我对代码的某些部分有一个简单的疑问,如下所示:

// A utility function to print the adjacenncy list representation of graph
void printGraph(struct Graph* graph)
{
    int v;
    for (v = 0; v < graph->V; ++v)
    {
        struct AdjListNode* pCrawl = graph->array[v].head;
        printf("\n Adjacency list of vertex %d\n head ", v);
        while (pCrawl)
        {
            printf("-> %d", pCrawl->dest);
            pCrawl = pCrawl->next;
        }
        printf("\n");
    }
}

因为,这里对于每个V while 循环执行说d 次,其中 d 是每个顶点的度数。

所以,我认为时间复杂度就像

d0 + d1 + d2 + d3 ....... +dV where di is the degree of each vertex.

所有这些加起来 O(E),但是链接说时间复杂度是 O(|V|+|E|)


不知道理解有什么问题。这里需要一些帮助

【问题讨论】:

  • 假设图没有边。算法需要多长时间?
  • @user2357112 我们必须检查或扫描每个顶点一次,对吗?但它是一个嵌套循环,所以时间复杂度不应该是这样吗?

标签: algorithm time-complexity breadth-first-search adjacency-list


【解决方案1】:

这里重要的是,为了使时间复杂度有效,我们需要涵盖所有可能的情况:

  • 无论图形结构如何,外部循环的执行时间为 O(|V|)。
    • 即使我们根本没有边,对于外循环的每次迭代,我们都必须执行恒定数量的操作 (O(1))
    • 内部循环对每条边执行一次,因此为 O(deg(v)) 次,其中 deg(v) 是当前节点的度数。
    • 因此,外循环的单次迭代的运行时间为 O(1 + deg(v))。请注意,我们不能省略 1,因为 deg(v) 可能为 0,但我们仍需要在该迭代中做一些工作
  • 总结一下,我们得到了 O(|V| * 1 + deg(v1) + deg(v2) + ...) = O(|V| + |E|) 的运行时间。

如前所述,|E|可能相当小,以至于我们仍然需要 说明仅在外循环中完成的工作。因此,我们不能简单地删除 |V|术语。

【讨论】:

  • 如果有 n 次迭代的外循环,那么时间复杂度应该是 O(V * E) 对吧?我在这里错过了什么?
  • 边的总数 E 只是你在循环的单次迭代中所做的工作量的一个非常悲观的上限。您可以通过注意到我们只查看每个顶点 v 的 degree(v) 出边以及一些额外的恒定工作(读取 v 的头指针)来做得更好。所有度数的总和是边数的两倍。因此,总的来说,我们只需要每个顶点和边的固定工作量(如最后一个要点中总结的)
猜你喜欢
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-10
相关资源
最近更新 更多