python - 图:从边缘列表更改为邻接列表表示的时间和空间复杂度,反之亦然
问题描述
我正在处理一个有向图,我对 Alberto Miranda 对Quora的解释如何得出时间复杂度感到困惑O(n+m)
[我假设他的意思O(V+E)
是顶点和边]。
可以在时间 O(n+m) 内将边列表 L 转换为邻接表表示 A。然后,可以在时间 O(n+m) 上对表示 A 执行 DFS,总共 O(n+m)。
这是我对从一种表示转换为另一种表示的理解:
对于从边缘列表到邻接列表的转换:
我的理解是,我们所要做的就是遍历每条边并添加到每个边列表中第一个顶点的邻接列表中,从而给出O(E)
. 我错过了什么?我假设n
和m
变量分别指的是顶点和边,但请随时纠正我。
对于从邻接列表到边缘列表的转换:
我尝试了这种转换,只是想看看他是否指的是逆转换。要从邻接列表切换,我必须遍历每个顶点,V
然后遍历 的每个V
边,E
给我O(V+E)
.
我写了代码来检查
这是我要表示的图表:需要注意的是,顶点 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)
给出结果
>>> 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]]
所以我的转换工作。
这些帖子与邻接列表有关,但没有提及时间复杂度。
解决方案
我的理解是,我们所要做的就是遍历每条边并添加到每个边列表中第一个顶点的邻接列表中,从而给出 O(E) 的时间复杂度。
将边缘列表转换为邻接列表确实是O(E)。有E个边,所以应该有E个操作。但是,打印(或呈现)邻接列表本身是O(V+E)。这就是为什么。
想一想,如果任何顶点之间没有边,你仍然必须遍历每个顶点,你最终会得到这样的结果:
{1: [], 2: [], 3: [], 4: [],... v: []}
所以V次操作是必须的。最重要的是,如果边确实存在,则必须为每个顶点打印相邻顶点。您必须总共打印E次相邻的顶点。总和为 O(V+E)。
总结:从边缘列表转换为邻接表:O(E) 呈现邻接表(独立于转换):O(V+E)
推荐阅读
- flutter - 如何扩展“冻结”抽象类
- react-native - 使用 React Native 沿线或路径为 SVG 对象设置动画
- javascript - 在我的新 div 中创建的 angular 指令加载组件而不是在外部
- r - 函数 read_excel() 在一个文件中解释“货币”数据类型完全错误,而在另一个文件中解释为好
- javascript - 问:使用 DOM 将 Javascript(通过链接到 HTML 文件)添加到自定义元素
- javascript - 纱表,拿不到/
- php - 由于网络爬虫导致的过度文件系统访问似乎破坏了容器文件系统
- react-native - React Native - 尝试在反应导航中创建一个带有选项卡导航器的抽屉,而不呈现选项卡的抽屉项目
- java - 从 jTextField 获取最终文本的预览
- python-3.x - RuntimeError:未安装 GnuPG