• 7.6.实现

    7.6.实现

    使用字典,很容易在 Python 中实现邻接表。在我们的 Graph 抽象数据类型的实现中,我们将创建两个类(见 Listing 1和 Listing 2),Graph(保存顶点的主列表)和 Vertex(将表示图中的每个顶点)。

    每个顶点使用字典来跟踪它连接的顶点和每个边的权重。这个字典称为connectedTo 。 下面的列表展示了 Vertex 类的代码。构造函数只是初始化 id ,通常是一个字符串和 connectedTo 字典。 addNeighbor方法用于从这个顶点添加一个连接到另一个。getConnections 方法返回邻接表中的所有顶点,如 connectedTo 实例变量所示。 getWeight 方法返回从这个顶点到作为参数传递的顶点的边的权重。

    1. class Vertex:
    2. def __init__(self,key):
    3. self.id = key
    4. self.connectedTo = {}
    5. def addNeighbor(self,nbr,weight=0):
    6. self.connectedTo[nbr] = weight
    7. def __str__(self):
    8. return str(self.id) + ' connectedTo: ' + str([x.id for x in self.connectedTo])
    9. def getConnections(self):
    10. return self.connectedTo.keys()
    11. def getId(self):
    12. return self.id
    13. def getWeight(self,nbr):
    14. return self.connectedTo[nbr]

    Listing 1

    下一个列表中显示的 Graph 类包含将顶点名称映射到顶点对象的字典。在 Figure 4中,该字典对象由阴影灰色框表示。 Graph 还提供了将顶点添加到图并将一个顶点连接到另一个顶点的方法。getVertices 方法返回图中所有顶点的名称。此外,我们实现了 iter 方法,以便轻松地遍历特定图中的所有顶点对象。 这两种方法允许通过名称或对象本身在图形中的顶点上进行迭代。

    1. class Graph:
    2. def __init__(self):
    3. self.vertList = {}
    4. self.numVertices = 0
    5. def addVertex(self,key):
    6. self.numVertices = self.numVertices + 1
    7. newVertex = Vertex(key)
    8. self.vertList[key] = newVertex
    9. return newVertex
    10. def getVertex(self,n):
    11. if n in self.vertList:
    12. return self.vertList[n]
    13. else:
    14. return None
    15. def __contains__(self,n):
    16. return n in self.vertList
    17. def addEdge(self,f,t,cost=0):
    18. if f not in self.vertList:
    19. nv = self.addVertex(f)
    20. if t not in self.vertList:
    21. nv = self.addVertex(t)
    22. self.vertList[f].addNeighbor(self.vertList[t], cost)
    23. def getVertices(self):
    24. return self.vertList.keys()
    25. def __iter__(self):
    26. return iter(self.vertList.values())

    Listing 2

    使用刚才定义的 GraphVertex 类,下面的 Python 会话创建 Figure 2中的图。首先我们创建 6 个编号为 0 到 5 的顶点。然后我们展示顶点字典。 注意,对于每个键 0 到 5,我们创建了一个顶点的实例。接下来,我们添加将顶点连接在一起的边。 最后,嵌套循环验证图中的每个边缘是否正确存储。 你应该在本会话结束时根据 Figure 2检查边列表的输出是否正确。

    1. >>> g = Graph()
    2. >>> for i in range(6):
    3. ... g.addVertex(i)
    4. >>> g.vertList
    5. {0: <adjGraph.Vertex instance at 0x41e18>,
    6. 1: <adjGraph.Vertex instance at 0x7f2b0>,
    7. 2: <adjGraph.Vertex instance at 0x7f288>,
    8. 3: <adjGraph.Vertex instance at 0x7f350>,
    9. 4: <adjGraph.Vertex instance at 0x7f328>,
    10. 5: <adjGraph.Vertex instance at 0x7f300>}
    11. >>> g.addEdge(0,1,5)
    12. >>> g.addEdge(0,5,2)
    13. >>> g.addEdge(1,2,4)
    14. >>> g.addEdge(2,3,9)
    15. >>> g.addEdge(3,4,7)
    16. >>> g.addEdge(3,5,3)
    17. >>> g.addEdge(4,0,1)
    18. >>> g.addEdge(5,4,8)
    19. >>> g.addEdge(5,2,1)
    20. >>> for v in g:
    21. ... for w in v.getConnections():
    22. ... print("( %s , %s )" % (v.getId(), w.getId()))
    23. ...
    24. ( 0 , 5 )
    25. ( 0 , 1 )
    26. ( 1 , 2 )
    27. ( 2 , 3 )
    28. ( 3 , 4 )
    29. ( 3 , 5 )
    30. ( 4 , 0 )
    31. ( 5 , 4 )
    32. ( 5 , 2 )

    Figure 2