图的问题:
图的实现:
邻接矩阵图表示法:顶点类-->;图类-->
1 class Vertex: 2 def __init__(self, node): 3 self.id = node #传进来顶点的名称 4 # Mark all nodes unvisited 5 self.visited = False 6 7 def addNeighbor(self, neighbor, G): 8 G.addEdge(self.id, neighbor) #建立邻居,想把哪一个顶点和这个顶点相连。把图给传进来。 9 10 def getConnections(self, G): #所有和你相连的顶点 11 return G.adjMatrix[self.id] 12 13 def getVertexID(self): #城市名称是什么 14 return self.id 15 16 def setVertexID(self, id): #设置城市名称 17 self.id = id 18 19 def setVisited(self): 20 self.visited = True 21 22 def __str__(self): 23 return str(self.id) 24 25 class Graph: 26 def __init__(self, numVertices=10, directed=False): #创建一个矩阵,默认10x10,无向图 27 self.adjMatrix = [[None] * numVertices for _ in range(numVertices)] 28 self.numVertices = numVertices #一共有多少个顶点 29 self.vertices = [] # list存放顶点-->dict{id:vertex} 30 self.directed = directed 31 for i in range(0, numVertices): 32 newVertex = Vertex(i) #对每一个顶点而言,存放的是Vertex对象,面向对象-->支持直接获取邻居、connections 33 self.vertices.append(newVertex) 34 35 def addVertex(self, vtx, id): #不允许扩展,添加顶点 36 if 0 <= vtx < self.numVertices: 37 self.vertices[vtx].setVertexID(id) 38 39 def getVertex(self, n): #给你一个名字,返回该名字对应的对象。list缺点:需要一个for循环,一个一个查找。 40 for vertxin in range(0, self.numVertices): 41 if n == self.vertices[vertxin].getVertexID(): 42 return vertxin 43 return None 44 45 def addEdge(self, frm, to, cost=0): # 得到一条路径 46 #print("from",frm, self.getVertex(frm)) 47 #print("to",to, self.getVertex(to)) 48 if self.getVertex(frm) is not None and self.getVertex(to) is not None: 49 self.adjMatrix[self.getVertex(frm)][self.getVertex(to)] = cost 50 if not self.directed: 51 # For directed graph do not add this 无向图-->双向添加 52 self.adjMatrix[self.getVertex(to)][self.getVertex(frm)] = cost 53 54 def getVertices(self): #得到所有的顶点 55 # ***create a copy, and return a copy *** 56 vertices = [] 57 for vertxin in range(0, self.numVertices): 58 vertices.append(self.vertices[vertxin].getVertexID()) 59 return vertices 60 61 # 为什么不能直接这样写return self.vertices-->内部的东西完全暴露出去了,所以只能返回一个备份 62 63 def printMatrix(self): 64 for u in range(0, self.numVertices): 65 row = [] 66 for v in range(0, self.numVertices): 67 row.append(str(self.adjMatrix[u][v]) if self.adjMatrix[u][v] is not None else '/') 68 print(row) 69 70 def getEdges(self): 71 edges = [] 72 for v in range(0, self.numVertices): 73 for u in range(0, self.numVertices): 74 if self.adjMatrix[u][v] is not None: 75 vid = self.vertices[v].getVertexID() 76 wid = self.vertices[u].getVertexID() 77 edges.append((vid, wid, self.adjMatrix[u][v])) 78 return edges 79 80 def getNeighbors(self, n): 81 neighbors = [] 82 for vertxin in range(0, self.numVertices): #找到该顶点 83 if n == self.vertices[vertxin].getVertexID(): 84 for neighbor in range(0, self.numVertices): 85 if (self.adjMatrix[vertxin][neighbor] is not None): 86 neighbors.append(self.vertices[neighbor].getVertexID()) 87 return neighbors 88 #有向图-->能到哪些点 89 90 def isConnected(self, u, v): 91 uidx = self.getVertex(u) 92 vidx = self.getVertex(v) 93 return self.adjMatrix[uidx][vidx] is not None 94 95 def get2Hops(self, u): 96 neighbors = self.getNeighbors(u) 97 print(neighbors) 98 hopset = set() 99 for v in neighbors: 100 hops = self.getNeighbors(v) 101 hopset |= set(hops) 102 return list(hopset)
缺点:不容易扩展;太多0浪费空间。
邻接列表图表示:
1 import sys 2 class Vertex: 3 def __init__(self, node): 4 self.id = node #城市名字 5 self.adjacent = {} #字典,存放所有邻居的字典 6 # Set distance to infinity for all nodes 7 self.distance = sys.maxsize 8 # Mark all nodes unvisited 9 self.visited = False 10 # Predecessor 11 self.previous = None 12 13 def addNeighbor(self, neighbor, weight=0): 14 self.adjacent[neighbor] = weight #添加一个邻居-->城市对象!!,cost 15 16 # returns a list 17 def getConnections(self): # neighbor keys 18 return self.adjacent.keys() #返回所有邻居名字 19 20 def getVertexID(self): 21 return self.id 22 23 def getWeight(self, neighbor): 24 return self.adjacent[neighbor] 25 26 def setDistance(self, dist): 27 self.distance = dist 28 29 def getDistance(self): 30 return self.distance 31 32 def setPrevious(self, prev): 33 self.previous = prev 34 35 def setVisited(self): 36 self.visited = True 37 38 def __str__(self): 39 return str(self.id) + ' adjacent: ' + str([x.id for x in self.adjacent]) 40 41 def __lt__(self, other): 42 return self.distance < other.distance and self.id < other.id 43 44 class Graph: 45 def __init__(self, directed=False): 46 # key is string, vertex id 47 # value is Vertex 48 self.vertDictionary = {} #顶点的字典,key存放城市名称,value存放该城市的对象 49 self.numVertices = 0 50 self.directed = directed 51 52 def __iter__(self): 53 return iter(self.vertDictionary.values()) 54 55 def isDirected(self): 56 return self.directed 57 58 def vectexCount(self): 59 return self.numVertices 60 61 def addVertex(self, node): #添加一个新的城市 62 self.numVertices = self.numVertices + 1 63 newVertex = Vertex(node) #创建一个新的城市对象,创建一个对象,这个对象是顶点 64 self.vertDictionary[node] = newVertex #把城市添加到顶点字典中 65 return newVertex 66 67 def getVertex(self, n): #不需要再写一个for循环一个一个查找,只要去字典中查找返回城市对象即可 68 if n in self.vertDictionary: 69 return self.vertDictionary[n] 70 else: 71 return None 72 73 def addEdge(self, frm, to, cost=0): 74 if frm not in self.vertDictionary: #如果不在顶点字典里面,先创建并加到字典中去-->新城市 75 self.addVertex(frm) 76 if to not in self.vertDictionary: 77 self.addVertex(to) 78 79 self.vertDictionary[frm].addNeighbor(self.vertDictionary[to], cost) 80 if not self.directed: 81 # For directed graph do not add this 82 self.vertDictionary[to].addNeighbor(self.vertDictionary[frm], cost) 83 84 def getVertices(self): #想知道所有的顶点,返回顶点字典的keys 85 return self.vertDictionary.keys() 86 87 def setPrevious(self, current): 88 self.previous = current 89 90 def getPrevious(self, current): 91 return self.previous 92 93 def getEdges(self): #想知道这幅图里面有多少条边 94 edges = [] 95 for key, currentVert in self.vertDictionary.items(): #首先要知道有多少个城市,currentVert存放的是城市对象 96 for nbr in currentVert.getConnections(): #列出每一个城市的邻居 97 currentVertID = currentVert.getVertexID() 98 nbrID = nbr.getVertexID() 99 edges.append((currentVertID, nbrID, currentVert.getWeight(nbr))) # tuple 100 return edges 101 102 def getNeighbors(self, v): 103 vertex = self.vertDictionary[v] 104 return vertex.getConnections()