图可以用 邻接矩阵 和 邻接表 (Adjacency List)来表示,当边数不多的时候,使用邻接表存储效率更高
如存储下面的图:
对应的邻接表为:
每一个顶点中存储了 顶点信息 + 相邻顶点信息,具有 addNeighbor()
, getId()
, getWeright()
等方法:
class Vertex:
def __init__(self, id):
self.id = id
self.adjacency = {}
def getId(self):
return self.id
def getNeighbors(self):
return self.adjacency.keys()
def addNeighbor(self, neighbor, weight):
self.adjacency[neighbor] = weight
def delNeighbor(self, neighbor):
if neighbor in adjacency.keys():
del self.adjacency[neighbor]
def getWeight(self, neighbor):
if neighbor in self.adjacency.keys():
return self.adjacency[neighbor]
return -1
def __str__(self):
res = str(self.id) + \
'\tadjacency: ' + str([(k, v) for (k, v) in self.adjacency.items()])
return res
if __name__ == '__main__':
v = Vertex(5)
v.addNeighbor(2, 6)
v.addNeighbor(3, 5)
print(v)
测试打印结果为:
5 adjacency: [(2, 6), (3, 5)]
符合预期要求
图的属性和方法如下:
from Vertex import Vertex
class Gragh:
def __init__(self):
self.numEdge = 0
self.numVertex = 0
# (key, value) = (id, Vertex(id))
self.vertexList = {}
def getNumEgde(self):
pass
def getNumVertex(self):
pass
def addVertex(self, id):
pass
def cost(self, fromVertex, toVertex):
pass
def getVertex(self, id):
pass
def addEdge(self, fromVertex, toVertex, weight):
pass
def delEdge(self, fromVertex, toVertex):
pass
def __str__(self):
pass
属性
初始化时存储了边的数量 numEdge
和顶点的数量 numVertex
其中 vertexList
是一个字典,字典的 key 为顶点的 id,字典的 value 为顶点(Vertex 类型,具有 id 和 adjacency 属性)
为了方便理解,利用 Gragh 创建图存储先前的图,内存中存储的数据如下:
方法
具体的方法定义如下:
from Vertex import Vertex
class Gragh:
def __init__(self):
self.vertexList = {}
self.numVertex = 0
self.numEdge = 0
def getNumEgde(self):
return self.numEdge
def getNumVertex(self):
return self.numVertex
def addVertex(self, id):
self.numVertex += 1
self.vertexList[id] = Vertex(id)
def getVertex(self, id):
if id in self.vertexList:
return self.vertexList[id]
else:
return None
def addEdge(self, fromVertex, toVertex, weight):
if fromVertex not in self.vertexList:
self.addVertex(fromVertex)
if toVertex not in self.vertexList:
self.addVertex(toVertex)
self.vertexList[fromVertex].addNeighbor(toVertex, weight)
self.numEdge += 1
def delEdge(self, fromVertex, toVertex):
if fromVertex in self.vertexList and toVertex in self.vertexList:
self.vertexList[fromVertex].delNeighbor(toVertex)
self.numEdge -= 1
def cost(self, fromVertex, toVertex):
if fromVertex in self.vertexList:
if toVertex in self.vertexList[fromVertex].getNeighbors():
return self.vertexList[fromVertex].getWeight(toVertex)
return -1
def __str__(self):
res = 'numEdge = ' + str(self.numEdge) + '\n' + \
'numVertex = ' + str(self.numVertex) + '\n'
for v in self.vertexList.values():
res += str(v) + '\n'
return res
测试
我们测试一下定义好的数据结构:
if __name__ == '__main__':
g = Gragh()
for i in ['V0', 'V1', 'V2', 'V3', 'V4', 'V5']:
g.addVertex(i)
print(g)
g.addEdge('V0', 'V1', 5)
g.addEdge('V0', 'V5', 2)
g.addEdge('V1', 'V2', 4)
g.addEdge('V2', 'V3', 9)
g.addEdge('V3', 'V4', 7)
g.addEdge('V3', 'V5', 3)
g.addEdge('V4', 'V0', 1)
g.addEdge('V5', 'V4', 1)
g.addEdge('V5', 'V5', 8)
print(g)
打印结果为:
numEdge = 0
numVertex = 6
V0 adjacency: []
V1 adjacency: []
V2 adjacency: []
V3 adjacency: []
V4 adjacency: []
V5 adjacency: []
numEdge = 9
numVertex = 6
V0 adjacency: [('V1', 5), ('V5', 2)]
V1 adjacency: [('V2', 4)]
V2 adjacency: [('V3', 9)]
V3 adjacency: [('V4', 7), ('V5', 3)]
V4 adjacency: [('V0', 1)]
V5 adjacency: [('V4', 1), ('V5', 8)]
结果正确
完结