diff --git a/codes/python/chapter_graph/graph_adjacency_matrix.py b/codes/python/chapter_graph/graph_adjacency_matrix.py index ecafbc564..80c8cc3f9 100644 --- a/codes/python/chapter_graph/graph_adjacency_matrix.py +++ b/codes/python/chapter_graph/graph_adjacency_matrix.py @@ -4,113 +4,88 @@ Created Time: 2023-02-23 Author: krahets (krahets@163.com) """ -import sys -from pathlib import Path - -sys.path.append(str(Path(__file__).parent.parent)) -from modules import Vertex, print_matrix - - -class GraphAdjMat: - """基于邻接矩阵实现的无向图类""" - +class ImprovedGraphAdjMat: def __init__(self, vertices: list[int], edges: list[list[int]]): - """构造方法""" - # 顶点列表,元素代表“顶点值”,索引代表“顶点索引” - self.vertices: list[int] = [] - # 邻接矩阵,行列索引对应“顶点索引” - self.adj_mat: list[list[int]] = [] - # 添加顶点 + self.vertex_map = {} # 用于存储顶点值到索引的映射 + self.vertices = [] + self.adj_mat = [] + for val in vertices: self.add_vertex(val) - # 添加边 - # 请注意,edges 元素代表顶点索引,即对应 vertices 元素索引 + for e in edges: self.add_edge(e[0], e[1]) - def size(self) -> int: - """获取顶点数量""" - return len(self.vertices) - def add_vertex(self, val: int): - """添加顶点""" - n = self.size() - # 向顶点列表中添加新顶点的值 + if val in self.vertex_map: + return # 如果顶点已存在,直接返回 + + index = len(self.vertices) + self.vertex_map[val] = index self.vertices.append(val) - # 在邻接矩阵中添加一行 - new_row = [0] * n - self.adj_mat.append(new_row) - # 在邻接矩阵中添加一列 - for row in self.adj_mat: - row.append(0) + + # 更新邻接矩阵 + if self.adj_mat: + for row in self.adj_mat: + row.append(0) + self.adj_mat.append([0] * (index + 1)) - def remove_vertex(self, index: int): - """删除顶点""" - if index >= self.size(): - raise IndexError() - # 在顶点列表中移除索引 index 的顶点 + def remove_vertex(self, val: int): + if val not in self.vertex_map: + return # 如果顶点不存在,直接返回 + + index = self.vertex_map[val] + + # 更新顶点列表和映射 self.vertices.pop(index) - # 在邻接矩阵中删除索引 index 的行 + del self.vertex_map[val] + for v in self.vertices[index:]: + self.vertex_map[v] -= 1 + + # 更新邻接矩阵 self.adj_mat.pop(index) - # 在邻接矩阵中删除索引 index 的列 for row in self.adj_mat: row.pop(index) - def add_edge(self, i: int, j: int): - """添加边""" - # 参数 i, j 对应 vertices 元素索引 - # 索引越界与相等处理 - if i < 0 or j < 0 or i >= self.size() or j >= self.size() or i == j: - raise IndexError() - # 在无向图中,邻接矩阵关于主对角线对称,即满足 (i, j) == (j, i) + def add_edge(self, v1: int, v2: int): + if v1 not in self.vertex_map or v2 not in self.vertex_map: + raise ValueError("Vertex not found") + + i, j = self.vertex_map[v1], self.vertex_map[v2] self.adj_mat[i][j] = 1 self.adj_mat[j][i] = 1 - def remove_edge(self, i: int, j: int): - """删除边""" - # 参数 i, j 对应 vertices 元素索引 - # 索引越界与相等处理 - if i < 0 or j < 0 or i >= self.size() or j >= self.size() or i == j: - raise IndexError() + def remove_edge(self, v1: int, v2: int): + if v1 not in self.vertex_map or v2 not in self.vertex_map: + raise ValueError("Vertex not found") + + i, j = self.vertex_map[v1], self.vertex_map[v2] self.adj_mat[i][j] = 0 self.adj_mat[j][i] = 0 def print(self): - """打印邻接矩阵""" print("顶点列表 =", self.vertices) print("邻接矩阵 =") - print_matrix(self.adj_mat) + for row in self.adj_mat: + print(row) +# 使用示例 +graph = ImprovedGraphAdjMat([1, 3, 2, 5, 4], [[1, 3], [1, 5], [3, 2], [2, 5], [2, 4], [5, 4]]) +print("\n初始化后,图为") +graph.print() -"""Driver Code""" -if __name__ == "__main__": - # 初始化无向图 - # 请注意,edges 元素代表顶点索引,即对应 vertices 元素索引 - vertices = [1, 3, 2, 5, 4] - edges = [[0, 1], [0, 3], [1, 2], [2, 3], [2, 4], [3, 4]] - graph = GraphAdjMat(vertices, edges) - print("\n初始化后,图为") - graph.print() +graph.add_edge(1, 2) +print("\n添加边 1-2 后,图为") +graph.print() - # 添加边 - # 顶点 1, 2 的索引分别为 0, 2 - graph.add_edge(0, 2) - print("\n添加边 1-2 后,图为") - graph.print() +graph.remove_edge(1, 3) +print("\n删除边 1-3 后,图为") +graph.print() - # 删除边 - # 顶点 1, 3 的索引分别为 0, 1 - graph.remove_edge(0, 1) - print("\n删除边 1-3 后,图为") - graph.print() +graph.add_vertex(6) +print("\n添加顶点 6 后,图为") +graph.print() - # 添加顶点 - graph.add_vertex(6) - print("\n添加顶点 6 后,图为") - graph.print() - - # 删除顶点 - # 顶点 3 的索引为 1 - graph.remove_vertex(1) - print("\n删除顶点 3 后,图为") - graph.print() +graph.remove_vertex(3) +print("\n删除顶点 3 后,图为") +graph.print()