简体   繁体   English

图:从边缘列表更改为邻接列表表示时的时间和空间复杂度,反之亦然

[英]Graph: time & space complexity of changing from edge list to adjacency list representation and vice versa

I am dealing with a directed graph and I was confused as to how Alberto Miranda's explanation on Quora arrived at the time complexity O(n+m) [I am assuming he means O(V+E) for vertices and edges]. 我正在处理一个有向图,而对于阿尔贝托·米兰达(Alberto Miranda)对Quora的解释是如何在时间复杂度O(n+m)上得出的[我假设他的顶点和边是O(V+E) ]感到困惑。

One can convert the edge list L into a adjacency list representation A in time O(n+m). 可以在时间O(n + m)中将边缘列表L转换为邻接列表表示A。 Then, one can perform the DFS on representation A in time O(n+m), for a total of O(n+m). 然后,可以在时间O(n + m)上对表示A执行DFS,总共进行O(n + m)。

Here's my understanding of converting from one representation to the other: 这是我从一种表示形式转换为另一种表示形式的理解:

For the conversion from edge list to adjacency list: 对于从边缘列表到邻接列表的转换:

My understanding is that all we have to do is go through each edge and add to the adjacency list of that first vertex in each edge list thereby giving the time complexity of O(E) . 我的理解是,我们要做的就是遍历每个边缘并将其添加到每个边缘列表中第一个顶点的邻接列表中,从而得出O(E)的时间复杂度。 What am I missing? 我想念什么? I assume that the n and m variables refer to vertices and edges respectively but feel free to correct me. 我假设nm变量分别引用顶点和边,但是可以随时进行校正。

For the conversion from adjacency list to edge list: 从邻接表到边缘表的转换:

I tried this conversion just to see if he were referring to the inverse conversion. 我尝试了这种转换,只是看他是否指的是逆转换。 To switch from the adjacency list, I would have to go through each vertex, V and then go through each of V 's edges, E giving me O(V+E) . 要从邻接列表切换,我必须遍历每个顶点V ,然后遍历V的每个边, E给我O(V+E)

I wrote the code for it to check 我写了代码检查

Here's the graph I am representing: The caveat is that vertex 3 is not a key in the adjacency list representation and so isn't included in conversion from adjacency list to edge list. 这是我所代表的图形:需要说明的是,顶点3不是邻接表表示中的关键,因此从邻接表到边列表的转换中不包括顶点3。

图表示

from collections import defaultdict

class AdjacencyListGraph:
  def __init__(self):
    self.graph = defaultdict(list)

  def addEdge(self, u, v):
    self.graph[u].append(v)

class EdgeListGraph:
  def __init__(self):
    self.graph = []

  def addEdge(self, u, v):
    self.graph.append([u, v])

  def addAllEdgesAtOnce(self, edgeList):
    self.graph = edgeList



def edgeListToAdjacencyList(edgeListGraph):
  adjacencyListGraph = AdjacencyListGraph()

  for edge in edgeListGraph.graph:
    adjacencyListGraph.addEdge(edge[0], edge[1])

  return adjacencyListGraph

def adjacencyListToEdgeList(adjacencyListGraph):
  edgeListGraph = EdgeListGraph()

  for vertex in adjacencyListGraph.graph.keys():
    for child in adjacencyListGraph.graph[vertex]:
      edgeListGraph.addEdge(vertex, child)

  return edgeListGraph

edgeList = [
              [1, 2],
              [2, 3],
              [1, 3],
              [4, 1],
              [4, 5],
              [5, 6],
              [6, 4]
]

edgeListGraph = EdgeListGraph()
edgeListGraph.addAllEdgesAtOnce(edgeList)
adjacencyListGraph = edgeListToAdjacencyList(edgeListGraph)
print(adjacencyListGraph.graph)

# trying to reverse the conversion
convertedEdgeListGraph = adjacencyListToEdgeList(adjacencyListGraph)
print(convertedEdgeListGraph.graph)

Giving results 给出结果

>>> defaultdict(<class 'list'>, {1: [2, 3], 2: [3], 4: [1, 5], 5: [6], 6: [4]})
>>> [[1, 2], [1, 3], [2, 3], [4, 1], [4, 5], [5, 6], [6, 4]]

So my conversions work. 因此我的转换有效。

These posts are related to adjacency lists but don't mention time complexity. 这些帖子与邻接列表有关,但没有提及时间复杂性。

Post 1 发布1

Post 2 发布2

My understanding is that all we have to do is go through each edge and add to the adjacency list of that first vertex in each edge list thereby giving the time complexity of O(E). 我的理解是,我们要做的就是遍历每个边缘并将其添加到每个边缘列表中第一个顶点的邻接列表中,从而得出O(E)的时间复杂度。

Converting an edge list to the adjacency list is indeed O(E) . 将边列表转换为邻接列表的确是O(E) There are E edges, so there should be E operations. E条边,因此应该有E条操作。 However, printing (or presenting) the adjacency list itself is O(V+E) . 但是,打印(或显示)邻接表本身是O(V + E) Here is why. 这就是为什么。

Think of, if there was no edge between any vertex, you have to still go through every vertex and you will end up with something like this: 想想看,如果任何顶点之间都没有边,那么您仍然必须遍历每个顶点,最终会得到如下结果:

{1: [], 2: [], 3: [], 4: [],... v: []}

So V number of operations is a must. 因此, V操作数是必须的。 On top of it, you have to print neighboring vertices for each vertex, if edges do exist. 最重要的是,如果存在边,则必须为每个顶点打印相邻的顶点。 You have to print the neighboring vertices in total E times. 您必须总共打印E次相邻的顶点。 That sums to O(V+E). 总计为O(V + E)。

To sum up: convert from edge list to adjacency list: O(E) presenting the adjacency list (independent from conversion): O(V+E) 总结:从边缘列表转换为邻接列表:O(E)表示邻接列表(与转换无关):O(V + E)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM