数据结构之图

图的问题:

 

 图的实现:

邻接矩阵图表示法:顶点类-->;图类-->

  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()

 

posted @ 2020-02-25 17:10  LinBupt  阅读(275)  评论(0编辑  收藏  举报