# 定义顶点节点
class Vertex(object):
def __init__(self, data):
"""
根据顶点值构造顶点节点
:param data: 顶点的值
"""
self.data = data # 数据域
self.firstIn = None # 以该顶点为弧头的边组成的链表的第一个节点
self.firstOut = None # 以该顶点为弧尾的边组成的链表的第一个节点
# 定义边(弧)节点
class Edge(object):
def __init__(self, headvex, tailvex):
"""
根据弧头和弧尾构造一个边(弧)节点
:param headvex: 弧头节点在顶点列表中的下标值
:param tailvex: 弧尾节点在顶点列表中的下标值
"""
self.headvex = headvex # 弧头顶点在顶点列表中的下标值
self.tailvex = tailvex # 弧尾顶点在顶点列表中的下标值
self.tlink = None # 和当前弧具有相同弧尾的下一个弧的链接
self.hlink = None # 和当前弧具有相同弧头的下一个弧的链接
# 定义十字链表
class OrthogonalList(object):
def __init__(self, vertexs, edges):
"""
根据顶点集合和边集合构造十字链表
:param vertexs: 顶点集合
:param edges: 边集合
"""
self.vlen = len(vertexs) # 顶点的数量
self.elen = len(edges) # 边的数量
# 构造顶点列表
self.vertexsList = [Vertex for i in range(self.vlen)] # 生成一个长度和顶点数据数量一样的空的顶点节点类型的列表
for i in range(self.vlen):
self.vertexsList[i] = Vertex(vertexs[i]) # 将顶点集合中的顶点一次添加到顶点数组中
# 添加每一条边到十字链表
for i in range(self.elen):
self.__addEdge(edges[i][0], edges[i][1])
# 根据指定的弧头弧尾的顶点值,将弧添加到十字链表中
def __addEdge(self, tail, head):
"""
根据指定的弧头弧尾的顶点值,将弧添加到十字链表中
:param tail: 弧尾顶点值
:param head: 弧头顶点值
"""
# 分别求出弧尾、弧头顶点在顶点列表中的下标值
tailvexIndex = self.__getPosition(tail)
headvexIndex = self.__getPosition(head)
# 构造新的边
newEdge = Edge(headvexIndex, tailvexIndex)
# 弧头、弧尾节点对应的顶点
tailvex = self.vertexsList[tailvexIndex]
headvex = self.vertexsList[headvexIndex]
# 将新的边添加到弧尾顶点的以该顶点为弧尾的边组成的链表中
if tailvex.firstOut is None:
tailvex.firstOut = newEdge
else:
e = tailvex.firstOut
while e.tlink is not None:
e = e.tlink
e.tlink = newEdge
# 将新的边添加到弧头顶点的以该顶点为弧头的边组成的链表中
if headvex.firstIn is None:
headvex.firstIn = newEdge
else:
e = headvex.firstIn
while e.hlink is not None:
e = e.hlink
e.hlink = newEdge
# 获取顶点在顶点列表中的下标值
def __getPosition(self, v):
"""
获取顶点在顶点列表中的下标值
:param v: 顶点
:return: 对应的下标
"""
for i in range(len(self.vertexsList)):
if self.vertexsList[i].data is v:
return i
return -1
# 求顶点入度(以顶点为弧头的边数)
def inDegree(self, v):
"""
求顶点的入度
:param v: 顶点
:return: 入度
"""
vex = self.vertexsList[self.__getPosition(v)] # 获取顶点在十字链表中的顶点列表中对应的元素
inD = 0 # 保存入度
h = vex.firstIn
while h is not None:
inD += 1
h = h.hlink
return inD
# 求顶点出度(以顶点为为弧尾的边数)
def outDegree(self, v):
"""
求顶点的出度
:param v: 顶点
:return: 出度
"""
vex = self.vertexsList[self.__getPosition(v)] # 获取顶点在十字链表中的顶点列表中对应的元素
outD = 0 # 保存出度
t = vex.firstOut
while t:
outD += 1
t = t.tlink
return outD
# 测试十字链表功能
if __name__ == '__main__':
vertex = [1, 2, 3, 4, 5]
edges = [[1, 2], [2, 3], [3, 1], [3, 4], [4, 1], [4, 5], [1, 5]]
o = OrthogonalList(vertex, edges)
for i in vertex:
print('顶点%d的入度和出度分别是:%d,%d' % (i, o.inDegree(i), o.outDegree(i)))
十字链表存储有向图(Python语言实现)
最新推荐文章于 2023-04-21 00:00:00 发布