Python无向图邻接表实现

bytetoy.cn

一、无向图邻接表表示

bytetoy.cn

Python使用邻接表实现无向图,使用Python的字典dict来实现,字典的健存储顶点,字典的值存储图的边。

使用字典的过程中,需要注意字典的几个基本操作,如:字典长度,添加健以及值。

构造函数

基于Python的字典实现无向图,仅需一个成员变量:self.graph_list = dict[str, list[str]]()

  • 字典的健key:顶点(str类型)
  • 字典的值value:是一个列表,存储顶点所链接的边(list[str]类型)
  • 为列便于理解,建议为变量添加注解,如:dict[str, list[str]]()
    def __init__(self, verts: str, edges: list[list[str]]):
        # 初始化一个字典,健为顶点,值为边(list)
        self.graph_list = dict[str, list[str]]()

        # 添加顶点,向字典中添加健
        for v in verts:
            self.add_vert(v)
        # 添加边,向字典中添加健的值
        for e in edges:
            self.add_edge(e[0], e[1])

二、无向图增加顶点

bytetoy.cn

为无向图增加一个顶点,即在字典中新增一个键值对,由于只增加列顶点,因此健的值为空[]

注意字典的操作方法:self.graph_list[v] = [],在字典新增一个健为v,但是值为[]

# 添加顶点:向字典添加健
    def add_vert(self, v):
        if v in self.graph_list:
            return
        # 仅添加顶点的健,暂无键值
        self.graph_list[v] = []

三、无向图删除顶点

bytetoy.cn

无向图删除一个顶点,需要进行两步操作方可完成:

  • 在字典中删除顶点对应的键值对;
  • 处理其他顶点有链接的边,因此需要对其他顶点进行遍历,通过while循环获取每一个顶点的键值,然后在键值中删除对应的顶点。
# 删除顶点,删除顶点的键值对,同时删除其他顶点内包含该顶点值中包含的顶点
    def remove_vert(self, v):
        if v not in self.graph_list:
            raise ValueError("查无此顶点")
        # 首先删除字典中v健的键值对
        self.graph_list.pop(v)
        # 遍历顶点和链表字典,逐个从字典中顶点对应的键值中,删除v顶点的边
        for vert in self.graph_list:
            if v in vert:
                self.graph_list[vert].remove(v)

四、无向图边操作

bytetoy.cn

无向图邻接表的边操作,与邻接矩阵类似,也是需要进行两次操作。对边的两个顶点都进行操作。

同样也要注意,不可为同一个顶点增加边,需要做一个前置的if判断。

# 增加边:同时修改两个顶点对应的键值
    def add_edge(self, vert1, vert2):
        if vert1 not in self.graph_list or vert2 not in self.graph_list or vert1 == vert2:
            raise ValueError('顶点不存在')
        self.graph_list[vert1].append(vert2)
        # 对键值做个排序,看起来舒服些
        self.graph_list[vert1].sort()
        self.graph_list[vert2].append(vert1)
        self.graph_list[vert2].sort()

    # 删除边:同时删除两个顶点对应的键值
    def remove_edge(self, vert1, vert2):
        if vert1 not in self.graph_list or vert2 not in self.graph_list or vert1 == vert2:
            raise ValueError('顶点不存在')
        self.graph_list[vert1].remove(vert2)
        self.graph_list[vert2].remove(vert1)

五、全部代码

class GraphList:
    # 基于字典实现无向图的邻接链表
    # 字典的健:顶点(str类型)
    # 字典的值:是一个列表,存储顶点所链接的边list[str]类型
    # edges: list[list[str]]:edges是一个列表,包含多条边,每条边list[str]也是一个列表,包含两个顶点
    def __init__(self, verts: str, edges: list[list[str]]):
        # 初始化一个字典,健为顶点,值为边(list)
        self.graph_list = dict[str, list[str]]()

        # 添加顶点,向字典中添加健
        for v in verts:
            self.add_vert(v)
        # 添加边,向字典中添加健的值
        for e in edges:
            self.add_edge(e[0], e[1])

    # 图的大小,就是顶点个数,即字典的长度
    def size(self):
        return len(self.graph_list)

    # 添加顶点:向字典添加健
    def add_vert(self, v):
        if v in self.graph_list:
            return
        # 仅添加顶点的健,暂无键值
        self.graph_list[v] = []

    # 删除顶点,删除顶点的键值对,同时删除其他顶点内包含该顶点值中包含的顶点
    def remove_vert(self, v):
        if v not in self.graph_list:
            raise ValueError("查无此顶点")
        # 首先删除字典中v健的键值对
        self.graph_list.pop(v)
        # 遍历顶点和链表字典,逐个从字典中顶点对应的键值中,删除v顶点的边
        for vert in self.graph_list:
            if v in vert:
                self.graph_list[vert].remove(v)

    # 增加边:同时修改两个顶点对应的键值
    def add_edge(self, vert1, vert2):
        if vert1 not in self.graph_list or vert2 not in self.graph_list or vert1 == vert2:
            raise ValueError('顶点不存在')
        self.graph_list[vert1].append(vert2)
        # 对键值做个排序,看起来舒服些
        self.graph_list[vert1].sort()
        self.graph_list[vert2].append(vert1)
        self.graph_list[vert2].sort()

    # 删除边:同时删除两个顶点对应的键值
    def remove_edge(self, vert1, vert2):
        if vert1 not in self.graph_list or vert2 not in self.graph_list or vert1 == vert2:
            raise ValueError('顶点不存在')
        self.graph_list[vert1].remove(vert2)
        self.graph_list[vert2].remove(vert1)


if __name__ == "__main__":
    verts = ['a', 'b', 'c', 'd', 'e']
    # edges = [
    #     [verts[0], verts[1]],
    #     [verts[0], verts[3]],
    #     [verts[1], verts[2]],
    #     [verts[2], verts[3]],
    #     [verts[2], verts[4]],
    #     [verts[3], verts[4]],
    #     ]
    edges = [['a', 'b'], ['a', 'd'], ['b', 'c'], ['c', 'd'], ['c', 'e'], ['d', 'e'], ]
    grap_list = GraphList(verts, edges)
    print("大小:",grap_list.size())
    print(grap_list.graph_list)

    grap_list.add_vert('f')
    grap_list.add_edge('b','f')
    print("大小:", grap_list.size())
    print(grap_list.graph_list)

    grap_list.remove_edge('d','e')
    print("大小:", grap_list.size())
    print(grap_list.graph_list)

    grap_list.remove_vert('c')
    print("大小:", grap_list.size())
    print(grap_list.graph_list)

results matching ""

    No results matching ""

    results matching ""

      No results matching ""