当实现稀疏图时,为了避免空间浪费会采用邻接表实现。
但是邻接表实现的图,查找某个顶点的入度边关联的另一个顶点时就比较麻烦,这时就可以采用图的十字链表实现
十字链表的关键点是,两个有相同弧头顶点的弧结点就有一个指针相连,两个有相同弧尾顶点的胡结点也会有一个指针相连
"""
图的十字链表表示
"""
import numpy as np
class ArcBox:
# 弧结点
def __init__(self, tail_vex, head_vex, head_link=None, tail_link=None, info=None):
self.tail_vex = tail_vex
self.head_vex = head_vex
self.head_link = head_link
self.tail_link = tail_link
self.info = info
class VexNode:
# 顶点
def __init__(self, data, first_in = None, first_out = None):
self.data = data
self.first_in = first_in
self.first_out = first_out
class OLGraph:
# Orthogonal List Graph
def __init__(self):
self.vex_list = np.array([], dtype=VexNode)
self.vex_num = 0
self.arc_num = 0
def locate_vex(self, vertex):
for i in range(self.vex_num):
if self.vex_list[i].data == vertex:
return i
return -1
def create(self, vertices: list, arcs: list):
self.vex_num = len(vertices)
self.arc_num = len(arcs)
for i in range(self.vex_num):
self.vex_list = np.append(
self.vex_list,
[VexNode(vertices[i])]
)
for i in range(self.arc_num):
tail_vex, head_vex, info = arcs[i]
tail_index = self.locate_vex(tail_vex)
head_index = self.locate_vex(head_vex)
arc = ArcBox(
tail_vex=tail_vex,
head_vex=head_vex,
head_link=head_index,
tail_link=tail_index,
info=info
)
arc.tail_link = self.vex_list[tail_index].first_out
arc.head_link = self.vex_list[head_index].first_in
self.vex_list[tail_index].first_out = arc
self.vex_list[head_index].first_in = arc
def print(self):
for vex in self.vex_list:
print(f"===== 打印顶点信息{vex.data} =====")
arc_out = vex.first_out
adj_out_vex = np.array([])
while arc_out:
adj_out_vex = np.append(
adj_out_vex,
arc_out.head_vex
)
arc_out = arc_out.tail_link
arc_in = vex.first_in
adj_in_vex = np.array([])
while arc_in:
adj_in_vex = np.append(
adj_in_vex,
arc_in.tail_vex
)
arc_in = arc_in.head_link
print("出度边的邻接点: {}".format(adj_out_vex))
print("入度边的邻接点: {}".format(adj_in_vex))
def test_1(self):
vertex = ["A", "B", "C", "D", "E", "F"]
arcs = [
["A", "B", 0],
["B", "C", 0],
["C", "D", 0],
["D", "E", 0],
["E", "F", 0],
["D", "B", 10],
["F", "A", 20]
]
self.create(vertex, arcs)
self.print()
def test_2(self):
vertex = ["A", "B", "C", "D", "E", "F"]
arcs = [
["A", "B", 0],
["A", "C", 0],
["A", "D", 0],
["A", "E", 0],
["A", "F", 0],
]
self.create(vertex, arcs)
self.print()
if __name__ == '__main__':
graph = OLGraph()
graph.test_2()