Python 实现邻接表的科普文章

在图论中,图是一种重要的数学概念,它由顶点(节点)和边(连接节点的链接)组成。图可以是有向图,也可以是无向图。为了方便地表示图,我们常常会使用邻接表(Adjacency List)作为存储表示法。邻接表是一种高效存储稀疏图的方法,它通过为每个顶点维护一个列表,来表示从该顶点出发的所有邻接顶点。

邻接表的基本概念

邻接表通常由一个数组和多个链表组合而成。数组的长度与图中顶点的数量相同,数组中的每个元素指向一个链表,链表中存储与该顶点相邻的所有顶点。在无向图中,如果顶点 A 与顶点 B 相邻,则在 A 的邻接表和 B 的邻接表中都应包含对方。

类图示例

下面是实现邻接表的类图。我们将定义一个 Graph 类,用于表示图,并在其中实现添加顶点和边的方法。

classDiagram
    class Graph {
        +add_vertex(vertex)
        +add_edge(vertex1, vertex2)
        +remove_vertex(vertex)
        +remove_edge(vertex1, vertex2)
        +get_neighbors(vertex)
    }

邻接表的实现

接下来,我们来实现一个简单的邻接表。我们将创建一个 Graph 类,其中包含表示图的基本操作。

class Graph:
    def __init__(self):
        self.adjacency_list = {}

    def add_vertex(self, vertex):
        if vertex not in self.adjacency_list:
            self.adjacency_list[vertex] = []

    def add_edge(self, vertex1, vertex2):
        if vertex1 not in self.adjacency_list:
            self.add_vertex(vertex1)
        if vertex2 not in self.adjacency_list:
            self.add_vertex(vertex2)
        self.adjacency_list[vertex1].append(vertex2)
        self.adjacency_list[vertex2].append(vertex1)  # For undirected graph

    def remove_vertex(self, vertex):
        if vertex in self.adjacency_list:
            del self.adjacency_list[vertex]
            for keys in self.adjacency_list:
                if vertex in self.adjacency_list[keys]:
                    self.adjacency_list[keys].remove(vertex)

    def remove_edge(self, vertex1, vertex2):
        if vertex1 in self.adjacency_list and vertex2 in self.adjacency_list:
            if vertex2 in self.adjacency_list[vertex1]:
                self.adjacency_list[vertex1].remove(vertex2)
            if vertex1 in self.adjacency_list[vertex2]:
                self.adjacency_list[vertex2].remove(vertex1)

    def get_neighbors(self, vertex):
        return self.adjacency_list.get(vertex, [])

    def __str__(self):
        return str(self.adjacency_list)

代码说明

  1. 初始化:构造函数中初始化一个空字典 adjacency_list 用于存储邻接表。
  2. 添加顶点add_vertex 方法检查顶点是否已存在,如果不存在,则将其添加到邻接表中。
  3. 添加边add_edge 方法添加一条边,并相应地更新邻接表。对于无向图,仅在两个顶点的邻接表中各添加对方。
  4. 删除顶点remove_vertex 方法从图中移除一个顶点及其所有相关边。
  5. 删除边remove_edge 方法从邻接表中移除两个顶点之间的边。
  6. 获取邻居get_neighbors 方法返回某个节点的所有邻居。
  7. 打印图__str__ 方法返回邻接表的字符串表示形式。

流程图

下面是图的一些基本操作的进行流程图。

flowchart TD
    A[开始] --> B{操作}
    B -->|添加顶点| C[调用 add_vertex]
    B -->|添加边| D[调用 add_edge]
    B -->|删除顶点| E[调用 remove_vertex]
    B -->|删除边| F[调用 remove_edge]
    B -->|获取邻居| G[调用 get_neighbors]
    B -->|打印图| H[调用 print]
    B -->|结束| I[结束]
    
    C --> B
    D --> B
    E --> B
    F --> B
    G --> B
    H --> B

使用示例

下面是如何使用上面实现的 Graph 类的一个示例:

if __name__ == "__main__":
    graph = Graph()
    
    graph.add_vertex("A")
    graph.add_vertex("B")
    graph.add_edge("A", "B")
    graph.add_edge("A", "C")
    
    print("Graph:", graph)  # 输出: Graph: {'A': ['B', 'C'], 'B': ['A'], 'C': ['A']}
    
    print("Neighbors of A:", graph.get_neighbors("A"))  # 输出: Neighbors of A: ['B', 'C']
    
    graph.remove_edge("A", "B")
    print("Graph after removing edge A-B:", graph)  # 输出: Graph after removing edge A-B: {'A': ['C'], 'B': [], 'C': ['A']}
    
    graph.remove_vertex("C")
    print("Graph after removing vertex C:", graph)  # 输出: Graph after removing vertex C: {'A': [], 'B': []}

结论

邻接表是一种高效而且常用于图的存储结构。它的灵活性和易用性使得它在许多算法实现中得到了广泛应用。通过本文的讲解与代码实例,相信读者对邻接表及其在 Python 中的实现有了更深入的了解。在实际应用中,无论是网络结构、社交网络还是路由算法,图的数据结构都扮演着不可或缺的角色。希望本篇文章能够帮助读者在图论及其应用中走得更远。