小规模图(顶点数<100)用二维列表更轻量;中大规模图推荐numpy数组,支持向量化运算且内存连续、访问更快。

邻接矩阵用二维列表还是 numpy 数组?
小规模图(顶点数 numpy 数组更快更稳。纯 Python 列表嵌套在索引和广播上不支持向量化,一不小心就写成 O(n²) 循环查边。
- 初始化:
np.zeros((n, n), dtype=int)比[[0]*n for _ in range(n)]更省内存且支持切片赋值 - 查边:
adj_matrix[u][v]和adj_matrix[u, v]都行,但后者是 numpy 原生语法,避免隐式类型转换出错 - 坑:用列表时若误写
[[0]*n]*n,所有行指向同一引用,改一行全变
邻接表为什么推荐用 defaultdict(list) 而不是普通字典?
因为图的顶点编号可能稀疏(比如只有节点 1、5、100),或动态添加新节点,普通字典每次查 graph.get(u, []) 冗余,而 defaultdict 在首次访问任意键时自动初始化空列表,写起来干净,也不怕 KeyError。
- 加边:
graph[u].append(v)直接可用,不用先判断u是否在字典里 - 遍历邻居:
for v in graph[u]:安全,即使u是孤立点(没出边),graph[u]也返回空列表 - 坑:用
dict手动初始化所有可能顶点(如{i: [] for i in range(n)})浪费空间,且无法支持非整数/非连续顶点(如字符串节点名)
networkx 里 to_numpy_matrix() 和 to_dict_of_lists() 的实际用途差异
这两个不是“替代关系”,而是不同下游任务的入口。你不需要自己实现邻接矩阵/表,但得知道它们输出结构是否匹配你的需求。
-
to_numpy_matrix()返回numpy.matrix(已弃用)或numpy.ndarray,适合做谱聚类、特征向量计算等线性代数操作 -
to_dict_of_lists()返回形如{0: [1,2], 1: [0]}的字典,适合快速查邻居、BFS/DFS 实现、或导出为 JSON - 坑:
to_numpy_matrix()默认按节点排序生成矩阵,但如果图节点是字符串(如['a','b','c']),它会按字典序排,导致索引和原始顺序不一致;此时应显式传参nodelist=['a','b','c']
稀疏图用邻接表,稠密图用邻接矩阵?别只看密度
密度只是参考,真正影响选择的是你要做什么操作。比如一个有 10⁵ 个节点、平均度数 3 的图,看着很稀疏,但如果你要频繁执行「对所有点对 (u,v),检查是否存在路径长度 ≤2」,那邻接矩阵的 adj @ adj 矩阵乘比遍历十万条链表快得多。
立即学习“Python免费学习笔记(深入)”;
- 查边存在性:邻接矩阵 O(1),邻接表平均 O(degree(u))
- 枚举所有边:邻接表 O(|E|),邻接矩阵 O(|V|²),哪怕图只有 1 条边也要扫完全部格子
- 内存:邻接矩阵固定占 O(|V|²),邻接表占 O(|V| + |E|);但 Python 中每个
list对象有额外开销,极小图(
邻接结构没有银弹。同一个图,可能前半段用邻接表做 BFS,后半段转成 scipy.sparse.csr_matrix 做 PageRank 迭代——关键不是选哪个“标准答案”,而是清楚每个结构在你当前操作下的时间/空间账怎么算。










