以下为图结构的python实现:
from enum import Enum
GraphType = Enum('GraphType', ('undirected', 'directed', 'weighted'))
class MatrixGraph():
"""邻接矩阵类"""
def __init__(self, vertex_list, edge_list, graph_type=GraphType.undirected):
"""
用给定的顶点列表和边列表初始化一个邻接矩阵,可指定图类型。
:param vertex_list: 顶点列表,包含图的所有顶点。
:param edge_list: 边列表,在有向图和无向图中,每个元素是由两个顶点组成的元组;在加权图中,每个元素是由两个顶点和权重组成的元组。
:param graph_type: 图类型,默认为无向图。
"""
self.vertex_list = vertex_list
self.adjacency_matrix = [[1 if i == j else 0 for j in self.vertex_list] for i in self.vertex_list] # 初始化邻接矩阵,对角线值为1,其他为0
self.graph_type = graph_type
self.add_edge(edge_list)
def add_edge(self, edge_list):
"""
将边列表中的顶点关系添加进邻接矩阵中。
:param edge_list: 边列表。
:return: None
"""
# 如果是有向图和无向图,邻接则将对应值置1
if len(edge_list[0]) == 2:
for v1, v2 in edge_list:
i1 = self.vertex_list.index(v1)
i2 = self.vertex_list.index(v2)
self.adjacency_matrix[i1][i2] = 1
if self.graph_type == GraphType.undirected: self.adjacency_matrix[i2][i1] = 1
# 如果是加权图,邻接则将对应值置为权重
elif len(edge_list[0]) == 3:
for v1, v2, weight in edge_list:
i1 = self.vertex_list.index(v1)
i2 = self.vertex_list.index(v2)
self.adjacency_matrix[i1][i2] = weight
self.adjacency_matrix[i2][i1] = weight
class LinkedListGraph():
"""邻接链表类"""
def __init__(self, vertex_list, edge_list, graph_type=GraphType.undirected):
self.adjacency_dict = {vertex: [] for vertex in vertex_list} # 初始化邻接字典
self.graph_type = graph_type
self.add_edge(edge_list)
def add_edge(self, edge_list):
"""将顶点的邻居添加进对应列表中。"""
for v1, v2 in edge_list:
self.adjacency_dict[v1].append(v2)
if self.graph_type == GraphType.undirected: self.adjacency_dict[v2].append(v1)
def DFS(self, vertex, visited_list=[]):
"""
深度优先搜索
:param vertex: 当前顶点
:param visited_list: 已访问顶点列表
:return: None
"""
print(vertex, end='\t')
visited_list.append(vertex)
for neighbor in self.adjacency_dict[vertex]:
if neighbor not in visited_list:
self.DFS(neighbor, visited_list)
def BFS(self, vertex, visited_list=[]):
"""广度优先搜索"""
if not visited_list:
print(vertex, end='\t')
visited_list.append(vertex)
visit_list = []
for neighbor in self.adjacency_dict[vertex]:
if neighbor not in visited_list:
print(neighbor, end='\t')
visit_list.append(neighbor)
visited_list.append(neighbor)
for neighbor in visit_list:
self.BFS(neighbor, visited_list)
def is_acyclic_graph(self, vertex, visited_list=[]):
"""判断是否为无环图"""
visited_list.append(vertex)
for neighbor in self.adjacency_dict[vertex]:
if neighbor in visited_list: return True
if self.is_acyclic_graph(neighbor, visited_list): return True
def top_sort(self):
"""拓扑排序"""
def get_zero_degree(in_degree_dict):
"""获取入度为0的顶点"""
return [key for key, value in in_degree_dict.items() if value == 0]
# 计算入度
in_degree_dict = {key: 0 for key in self.adjacency_dict}
for neighbor_list in self.adjacency_dict.values():
for neighbor in neighbor_list:
in_degree_dict[neighbor] += 1
# 如果是有向图且为无环图,则进行拓扑排序。
if self.graph_type == GraphType.directed and self.is_acyclic_graph(get_zero_degree(in_degree_dict)[0]):
# 每次输出入度为0的顶点,并将其指向的所有顶点入度减1。
while get_zero_degree(in_degree_dict):
for vertex in get_zero_degree(in_degree_dict):
print(vertex, end='\t')
for neighbor in self.adjacency_dict[vertex]:
in_degree_dict[neighbor] -= 1
del in_degree_dict[vertex]
else: print('不是DAG,不可拓扑排序!')
if __name__ == '__main__':
vertex_list = ['a', 'b', 'c', 'd', 'e', 'f']
edge_list = [('a', 'b'), ('a', 'c'), ('b', 'd'), ('c', 'e'), ('c', 'f')]
obj = MatrixGraph(vertex_list, edge_list)
print('邻接矩阵:', obj.adjacency_matrix)
obj = LinkedListGraph(vertex_list, edge_list)
print('邻接链表:', obj.adjacency_dict)
print('DFS遍历:'); obj.DFS('a')
print('\n', 'BFS遍历:'); obj.BFS('a')
vertex_list = [chr(i) for i in range(65, 78)]
edge_list = [('A', 'B'), ('A', 'F'), ('A', 'G'), ('C', 'A'), ('C', 'D'), ('D', 'F'), ('F', 'E'), ('G', 'E'),
('G', 'J'), ('H', 'G'), ('I', 'H'), ('J', 'K'), ('J', 'L'), ('J', 'M'), ('L', 'M')]
obj = LinkedListGraph(vertex_list, edge_list, GraphType.directed)
print('\n', 'DAG:', obj.adjacency_dict)
print('拓扑排序:'); obj.top_sort()
输出:
邻接矩阵: [[1, 1, 1, 0, 0, 0], [1, 1, 0, 1, 0, 0], [1, 0, 1, 0, 1, 1], [0, 1, 0, 1, 0, 0], [0, 0, 1, 0, 1, 0], [0, 0, 1, 0, 0, 1]]
邻接链表: {'a': ['b', 'c'], 'b': ['a', 'd'], 'c': ['a', 'e', 'f'], 'd': ['b'], 'e': ['c'], 'f': ['c']}
DFS遍历:
a b d c e f
BFS遍历:
a b c d e f
DAG: {'A': ['B', 'F', 'G'], 'B': [], 'C': ['A', 'D'], 'D': ['F'], 'E': [], 'F': ['E'], 'G': ['E', 'J'], 'H': ['G'], 'I': ['H'], 'J': ['K', 'L', 'M'], 'K': [], 'L': ['M'], 'M': []}
拓扑排序:
C I A D H B F G E J K L M