稀疏图:数据结构中对于稀疏图的定义为:有很少条边或弧(边的条数 ∣ E ∣ |E| ∣E∣ 远小于 ∣ V ∣ 2 |V|^2 ∣V∣2)的图称为稀疏图,反之边的条数 ∣ E ∣ |E| ∣E∣ 接近 ∣ V ∣ 2 |V|^2 ∣V∣2,称为稠密图。采用直观的办法来存储图往往会造成极大的空间浪费,因此需要采取其他方式压缩存储空间。
matrix,matrix[i][j] = x 表示结点 i 与结点 j 之间的边的长度为 x。我们可以看到在图1a的矩阵 matrix 中,除了少数结点间有边相连,大多数的存储空间都浪费了。matrix 中的非零元素以及这些元素的位置,也就是以三元组的方式存储 (i, j, x)。(i, j, x) 同样表示结点 i 与结点 j 之间的边的长度为 x,如图1b所示。
图1 COO表示
ro[i]就代表了 data[ro[i]] 与 data[ro[i+1]] 之间的元素的横坐标为 i(包括data[ro[i]] 但不包括 data[ro[i+1]])。ro[0]=0。ro[1]=2。ro[2]=4。ro[3]=5。ro[4]=7。
图2 CSR表示
第一小节中我们讨论了普通稀疏图的矩阵转化为COO表示。但如果邻接矩阵中只记录了两个结点是否相连,并没有记录边的信息(如图3a),我们便不需要记录 data 数据,如此可以进一步压缩存储空间。

图3 adj_coo表示
与adj_coo情况类似,如果邻接矩阵中只记录了两个结点是否相连,并没有记录边的信息(如图4a),我们便不需要记录 data 数据,如此可以进一步压缩存储空间。

图4 adj_csr表示
这里仅展示 adj_coo 转 adj_csr 的代码:
def adjcoo2adjcsr(adj_coo, node_count):
sour = adj_coo[0]
dist = adj_coo[1]
adjs = []
last = -1
for i in range(node_count):
try:
index = sour.index(i)
except:
index = last + 1
else:
last = index
finally:
adjs.append(index)
adjs.append(len(dist))
print(adjs)
print(dist)
adj_coo = [[0, 0, 1, 1, 2, 3, 3],
[0, 1, 1, 2, 0, 2, 3]]
adjcoo2adjcsr(adj_coo, 4)
运行结果如下图所示:
