python数据结构实现(六)
1. 图
1.1 python实现图的邻接矩阵表示方法
1.1.1 python实现无向无权图
- 通过传入一个二维数组确立邻接矩阵,无向无权图的邻接矩阵元素为0和1;
- adjMatrix[ i ][ j ] = 0 说明顶点i和j不连接,若为1则说明连接;
- 无向图的邻接矩阵总是为对称矩阵
import numpy as np
class MatrixGraph:
'''
无向图的邻接矩阵表示(为对称矩阵)
用矩阵存储顶点间的关系:顶点a与顶点b相连,则adjMatrix[vex2num[a],vex2num[b]]
的值为1,否则为0
vex2num为字典,将顶点映射为矩阵的编号
'''
def __init__(self,vertex=[]):
'''
根据传入的顶点信息表建造邻接矩阵和顶点字典
:param vertex:无向图的所有顶点组成的列表
'''
self.vexNum = len(vertex)
self.adjMatrix = np.zeros((self.vexNum,self.vexNum))
self.vex2num = {}
for index, vertex in enumerate(vertex):
self.vex2num[vertex] = index
def createGraph(self, maxtrix):
'''
传入一个矩阵确立顶点间的关系
'''
if maxtrix.shape == self.adjMatrix.shape:
self.adjMatrix = maxtrix
else:
raise Exception('wrong matrix shape')
def isLinked(self, vex1, vex2):
# 判断图中两个顶点是否连接
return self.adjMatrix[self.vex2num[vex1], self.vex2num[vex2]] == 1
def linkVex(self, vex1, vex2):
# 连接无向图的两个顶点
if vex1 != vex2:
self.adjMatrix[self.vex2num[vex1], self.vex2num[vex2]] = 1
self.adjMatrix[self.vex2num[vex2], self.vex2num[vex1]] = 1
def splitVex(self, vex1, vex2):
# 断开无向图的两个顶点
self.adjMatrix[self.vex2num[vex1], self.vex2num[vex2]] = 0
self.adjMatrix[self.vex2num[vex2], self.vex2num[vex1]] = 0
生成无向无权图:
vexs = ['a','b','c','d','e']
Mgraph = MatrixGraph(vexs)
matrix = np.array([[0,1,1,0,0],[1,0,1,1,0],\
[1,1,0,1,0],[0,1,1,0,1],[0,0,0,1,0]])
Mgraph.createGraph(matrix)
print(Mgraph.adjMatrix)
Mgraph.isLinked('a','d')
=====================================
[[0 1 1 0 0]
[1 0 1 1 0]
[1 1 0 1 0]
[0 1 1 0 1]
[0 0 0 1 0]]
False
1.1.2 python实现无向有权图
- 无向有权图与无向无权图的区别仅在与邻接矩阵中的元素
- adjMatrix[i][j] 为路权大小则说明顶点i和j相连;若为inf则说明两个顶点间没有直接路径,即不相连
import numpy as np
inf = float('inf')
class MatrixGraph:
'''
无向有权图的邻接矩阵表示(为对称矩阵)
用矩阵存储顶点间的关系:顶点a与顶点b相连,则adjMatrix[vex2num[a],vex2num[b]]的值为路权,否则为inf
vex2num为字典,将顶点映射为矩阵的编号
'''
def __init__(self,vertex=[]):
'''
根据传入的顶点信息表建造邻接矩阵和顶点字典
:param vertex:无向图的所有顶点组成的列表
'''
self.vex2num = {}
self.vexNum = len(vertex)
self.adjMatrix = np.array([[inf]*self.vexNum]*self.vexNum)
for index, vertex in enumerate(vertex):
self.vex2num[vertex] = index
def createGraph(self, maxtrix):
'''
传入一个带权矩阵确立顶点间的关系
'''
if maxtrix.shape == self.adjMatrix.shape:
self.adjMatrix = maxtrix
else:
raise Exception('wrong matrix shape')
def isLinked(self, vex1, vex2):
return not self.adjMatrix[self.vex2num[vex1], self.vex2num[vex2]] == inf
def linkVex(self, vex1, vex2, weight):
# 连接无向图的两个顶点
if vex1 != vex2:
self.adjMatrix[self.vex2num[vex1], self.vex2num[vex2]] = weight
self.adjMatrix[self.vex2num[vex2], self.vex2num[vex1]] = weight
def splitVex(self, vex1, vex2):
# 断开无向图的两个顶点
self.adjMatrix[self.vex2num[vex1], self.vex2num[vex2]] = inf
self.adjMatrix[self.vex2num[vex2], self.vex2num[vex1]] = inf
生成无向有权图:
vexs = ['a','b','c','d','e']
Mgraph = MatrixGraph(vexs)
matrix = np.array([[inf,9,12,inf,9],[9,inf,7,10,inf],[12,7,inf,3,inf],\
[inf,10,3,inf,14],[9,inf,inf,14,inf]])
Mgraph.createGraph(matrix)
print(Mgraph.adjMatrix)
print(Mgraph.isLinked('a','d'))
Mgraph.linkVex('a','d', 11)
print(Mgraph.adjMatrix)
print(Mgraph.isLinked('a','d'))
=================================
[[inf 9. 12. inf 9.]
[ 9. inf 7. 10. inf]
[12. 7. inf 3. inf]
[inf 10. 3. inf 14.]
[ 9. inf inf 14. inf]]
False
[[inf 9. 12. 11. 9.]
[ 9. inf 7. 10. inf]
[12. 7. inf 3. inf]
[11. 10. 3. inf 14.]
[ 9. inf inf 14. inf]]
True