链式前向星是一种非常优秀地存储图的方式,在存储过程中,我们采用链式方式存储每个点连接的边,相比于邻接表存储,优势在于可以更好地分配内存,不用受到python等语言中开数组动态的特点导致的数组空间浪费
通常不需要使用链式前向星
看网上都是通过c++来实现链式前向星的,遂使用python给后来者一些参考(狗头保命)
对链式前向星的原理做一些解释,如图,如果我们的数据如下
4
1 2 20
1 3 50
2 4 80
3 1 90
其中1 2 20 表示从点1到点2有一条边权为20的边
如果是采用邻接表方式,我们是将[2,20]加入字典或者列表的方式,而采用链式前向星的方式,我们是对每一条边编号,这个编号来自于边输进来的顺序,每个前向星中有三个属性,e1表示对于编号为cnt的边,边的终点是什么,w1自然表示边权
重点在于h1这一个属性,他指的是与u相连的上一条边的编号,通过从头遍历到尾的方式,我们就可以知道所有与u这个节点连接的边
下面是代码
#********************************************
# * Author: liuaaa
# ********************************************
#n表示顶点个数,m表示边个数
n = 10000
m = int(1e4)+10
#此处假设是无向边,需乘2
e1 = [0 for i in range(m<<1)]
w1 = [0 for i in range(m<<1)]
ne1 = [0 for i in range(m<<1)]
h1 = [-1 for i in range(n)]
cnt = 0#作为标注每一条边的唯一标志
#加边
def add(u,v,w):
global cnt#cnt为全局变量
w1[cnt] = w#存边权
e1[cnt] = v#存顶点值
ne1[cnt] = h1[u]#存u这一个节点的前驱顶点的下标
h1[u] = cnt#h[u]指向v所在下标,v为边的终点,可以理解为是从u这个节点向后垂下一条链,链上是他链接的边,但是遍历时是反向的,故顺序没变,顺序是边输进来的顺序
cnt+=1#最终cnt必然等于边数+1
for p in range(int(input())):
a,b,c = map(int,input().split())
add(a,b,c)
for j in range(1,5):#遍历所有的节点,去看其连接边的情况
i = h1[j]
while i != -1:
print(e1[i],w1[i])#输出连接节点及其边权
i = ne1[i]#注意输出不包括点自己
执行结果如下
3 50 2 20 4 80 1 90
如有错误,欢迎斧正,谢谢