Python无向图邻接矩阵实现

bytetoy.cn

一、无向图邻接矩阵表示

bytetoy.cn

Python使用邻接矩阵实现无向图,通过两个列表存储数据:一个列表存储顶点,一个二维列表存储边。

构造函数

邻接矩阵构造函数内含两个成员变量:

  • 顶点:一维列表存储顶点,self.verts = []
  • :二维列表构成一个N*N矩阵(N为顶点个数),相连的两个顶点在对应的行和列位置填充1,未相连填充0self.mats = []
    def __init__(self, verts, edges):
        # 顶点是一个列表
        self.verts = []
        # 边是一个二维列表,是根据顶点N×N的二维列表(数组)
        self.mats = []
        for v in verts:
            self.add_vert(v)

        for e in edges:
            self.add_edge(e[0], e[1])

二、无向图增加顶点

bytetoy.cn

增加顶点有三个操作步骤:

  1. 在顶点列表中新增一个元素:self.verts.append(val)

  2. 在边列表中新增一行:self.mats.append(row)

  3. 在边列表中新增一列,即为每一行新增一个元素,通过while循环遍历列表中的每一行,然后在行中增加一列(包含上一步中新增的一行):```

    for row in self.mats:
        row.append(0)
    
# 添加顶点
    def add_vert(self, val):
        #
        n = self.size()
        # 顶点列表添加新元素
        self.verts.append(val)
        row = [0] * n
        # 边列表添加一行
        self.mats.append(row)
        # 边列表添加一列(每一行增加一个元素)
        for row in self.mats:
            row.append(0)

三、无向图删除顶点

bytetoy.cn

删除顶点与增加顶点步骤相同,唯一不同点是增加顶点是在顶点列表的尾部添加(append),而删除顶点则是可能删除任意顶点,因此pop需要指定下标,同样三个步骤:

  1. 顶点列表中删除(pop)一个顶点元素:self.verts.pop(i)

  2. 边列表中删除指定顶点所在的行:self.mats.pop(i)

  3. 边列表中删除一列,即为每一行删除一个元素,通过while循环遍历边列表的每一行,然后在行中删除指定的下标元素:```

    for row in self.mats:
        row.pop(i)
    
# 删除顶点,根据顶点的索引删除
    def remove_vert(self, i):
        if self.size() == 0:
            raise IndexError("矩阵为空")
        # 顶点列表移除指定索引顶点
        self.verts.pop(i)
        # 边列表移除指定索引顶点行
        self.mats.pop(i)
        # 按行遍历边列表,逐行删除指定索引所在的列
        for row in self.mats:
            row.pop(i)

四、无向图边操作

bytetoy.cn

无向图中的边操作:新增和删除相对比较简单。唯一需要注意的是,边连接的是两个顶点,而邻接矩阵是对角线对称的,因此需要操作两次,即对顶点的行和列均需要进行操作。

注意:增加、删除边时,不能为同一个顶点增加边if r < 0 or c < 0 or r >= self.size() or c >= self.size() or r == c:

# c:行索引,r:列索引
    def add_edge(self, r, c):
        if r < 0 or c < 0 or r >= self.size() or c >= self.size() or r == c:
            raise IndexError('越界')
        self.mats[r][c] = 1
        self.mats[c][r] = 1

    def remove_edge(self, r, c):
        if r < 0 or c < 0 or r >= self.size() or c >= self.size() or r == c:
            raise IndexError('越界')
        self.mats[r][c] = 0
        self.mats[c][r] = 0

五、全部代码

from prettytable import PrettyTable


class GraphMatrix:
    def __init__(self, verts, edges):
        # 顶点是一个列表
        self.verts = []
        # 边是一个二维列表,是根据顶点N×N的二维列表(数组)
        self.mats = []
        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.verts)

    # 添加顶点
    def add_vert(self, val):
        #
        n = self.size()
        # 顶点列表添加新元素
        self.verts.append(val)
        row = [0] * n
        # 边列表添加一行
        self.mats.append(row)
        # 边列表添加一列(每一行增加一个元素)
        for row in self.mats:
            row.append(0)

    # 删除顶点,根据顶点的索引删除
    def remove_vert(self, i):
        if self.size() == 0:
            raise IndexError("矩阵为空")
        # 顶点列表移除指定索引顶点
        self.verts.pop(i)
        # 边列表移除指定索引顶点行
        self.mats.pop(i)
        # 按行遍历边列表,逐行删除指定索引所在的列
        for row in self.mats:
            row.pop(i)

    # c:行索引,r:列索引
    def add_edge(self, r, c):
        if r < 0 or c < 0 or r >= self.size() or c >= self.size() or r == c:
            raise IndexError('越界')
        self.mats[r][c] = 1
        self.mats[c][r] = 1

    def remove_edge(self, r, c):
        if r < 0 or c < 0 or r >= self.size() or c >= self.size() or r == c:
            raise IndexError('越界')
        self.mats[r][c] = 0
        self.mats[c][r] = 0

    def show(self):
        tb = PrettyTable(self.verts)
        for c in self.mats:
            tb.add_row(c)
        print(tb)


if __name__ == "__main__":
    verts = ['a', 'b', 'c', 'd', 'e']
    edges = [[0, 1], [0, 3], [1, 2], [2, 3], [2, 4], [3, 4]]
    matrix = GraphMatrix(verts, edges)
    matrix.show()

    matrix.add_vert('f')
    matrix.add_edge(1, 5)
    matrix.show()

    matrix.remove_vert(4)
    matrix.show()

    matrix.remove_edge(0, 3)
    matrix.show()

results matching ""

    No results matching ""

    results matching ""

      No results matching ""