1. 图的相关概念
树是一种特殊的图,相比树,图更能用来表示现实世界中的的实体,如路线图,网络节点图,课程体系图等,一旦能用图来描述实体,能模拟和解决一些非常复杂的任务。图的相关概念和词汇如下:
顶点vertex:图的节点
边Edge:顶点间的连线,若边具有方向时,组成有向图(directed graph)
权重weight:从一个顶点到其他不同顶点的距离不一样,因此边具有权重,来表示不同的距离
路径path:从一个顶点到另一个的所有边的集合
回路cycle:在有向图中,从一个顶点开始,最后又回到起始顶点的路径为一个回路
图可以表示为G={V,E},其中V为顶点的集合,E为边的集合,如下图所示:
2,图的实现
图的相关操作如下:
Graph() #创建图 addVertex(vert) #添加顶点 addEdge(fromVert, toVert) #添加边 addEdge(fromVert, toVert, weight) #添加边及其权重 getVertex(vertKey) #获取某个顶点 getVertices() #获取所有顶点 in #判断是否包括某个顶点
可以通过邻接矩阵(adjacency matrix)或领接表(adjacency list)来实现图。邻接矩阵表示图的结构如下,图中的数字表示两个顶点相连,且边的权重为该值。可以发现邻接矩阵更加适合于边较多的图,不然会造成内存空间的浪费。
邻接表表示图的结构如下,一个主列表中包含图的所有顶点,每个顶点又各包含列表记录与其相连的边。可以发现邻接表更适合边较少的图。
python实现邻接表代码如下:
#coding:utf-8 class Vertex(object): def __init__(self,key): self.id=key self.connectedTo={} def __str__(self): return str(self.id) + "connected to" +str([x.id for x in self.connectedTo]) #nbr为vertex对象 def addNeighbor(self,nbr,weight=0): self.connectedTo[nbr]=weight def getConnections(self): return self.connectedTo.keys() def getId(self): return self.id def getWeight(self,nbr): return self.connectedTo[nbr] class Graph(object): def __init__(self): self.vertList = {} self.numVertices = 0 def addVertex(self,key): newVertex = Vertex(key) self.vertList[key]=newVertex self.numVertices +=1 return newVertex def getVertex(self,key): if key in self.vertList: return self.vertList[key] else: return None def __contains__(self, key): return key in self.vertList #fromVert,toVert为起始和终止节点的key def addEdge(self,fromVert,toVert,weight=0): if fromVert not in self.vertList: self.addVertex(fromVert) if toVert not in self.vertList: self.addVertex(toVert) self.vertList[fromVert].addNeighbor(self.vertList[toVert],weight) def getVertices(self): return self.vertList.keys() def __iter__(self): return iter(self.vertList.values()) if __name__ == '__main__': g = Graph() for i in range(6): g.addVertex(i) g.addEdge(0, 1, 5) g.addEdge(0, 5, 2) g.addEdge(1, 2, 4) g.addEdge(2, 3, 9) g.addEdge(3, 4, 7) g.addEdge(3, 5, 3) g.addEdge(4, 0, 1) g.addEdge(5, 4, 8) g.addEdge(5, 2, 1) for v in g: for w in v.getConnections(): print("( %s , %s )" % (v.getId(), w.getId()))