图的十字链表实现(Python)

当实现稀疏图时,为了避免空间浪费会采用邻接表实现。

但是邻接表实现的图,查找某个顶点的入度边关联的另一个顶点时就比较麻烦,这时就可以采用图的十字链表实现

十字链表的关键点是,两个有相同弧头顶点的弧结点就有一个指针相连,两个有相同弧尾顶点的胡结点也会有一个指针相连

"""
图的十字链表表示
"""
import numpy as np


class ArcBox:
    # 弧结点
    def __init__(self, tail_vex, head_vex, head_link=None, tail_link=None, info=None):
        self.tail_vex = tail_vex
        self.head_vex = head_vex
        self.head_link = head_link
        self.tail_link = tail_link
        self.info = info


class VexNode:
    # 顶点
    def __init__(self, data, first_in = None, first_out = None):
        self.data = data
        self.first_in = first_in
        self.first_out = first_out


class OLGraph:
    # Orthogonal List Graph
    def __init__(self):
        self.vex_list = np.array([], dtype=VexNode)
        self.vex_num = 0
        self.arc_num = 0

    def locate_vex(self, vertex):
        for i in range(self.vex_num):
            if self.vex_list[i].data == vertex:
                return i
        return -1

    def create(self, vertices: list, arcs: list):
        self.vex_num = len(vertices)
        self.arc_num = len(arcs)
        for i in range(self.vex_num):
            self.vex_list = np.append(
                self.vex_list,
                [VexNode(vertices[i])]
            )
        for i in range(self.arc_num):
            tail_vex, head_vex, info = arcs[i]
            tail_index = self.locate_vex(tail_vex)
            head_index = self.locate_vex(head_vex)
            arc = ArcBox(
                tail_vex=tail_vex, 
                head_vex=head_vex,
                head_link=head_index, 
                tail_link=tail_index, 
                info=info
            )
            arc.tail_link = self.vex_list[tail_index].first_out
            arc.head_link = self.vex_list[head_index].first_in
            self.vex_list[tail_index].first_out = arc
            self.vex_list[head_index].first_in = arc

    def print(self):
        for vex in self.vex_list:
            print(f"===== 打印顶点信息{vex.data} =====")
            arc_out = vex.first_out
            adj_out_vex = np.array([])
            while arc_out:
                adj_out_vex = np.append(
                    adj_out_vex, 
                    arc_out.head_vex
                )
                arc_out = arc_out.tail_link

            arc_in = vex.first_in
            adj_in_vex = np.array([])
            while arc_in:
                adj_in_vex = np.append(
                    adj_in_vex, 
                    arc_in.tail_vex
                )
                arc_in = arc_in.head_link
            print("出度边的邻接点: {}".format(adj_out_vex))
            print("入度边的邻接点: {}".format(adj_in_vex))

    def test_1(self):
        vertex = ["A", "B", "C", "D", "E", "F"]
        arcs = [
            ["A", "B", 0],
            ["B", "C", 0],
            ["C", "D", 0],
            ["D", "E", 0],
            ["E", "F", 0],
            ["D", "B", 10],
            ["F", "A", 20]
        ]
        self.create(vertex, arcs)
        self.print()

    def test_2(self):
        vertex = ["A", "B", "C", "D", "E", "F"]
        arcs = [
            ["A", "B", 0],
            ["A", "C", 0],
            ["A", "D", 0],
            ["A", "E", 0],
            ["A", "F", 0],
        ]
        self.create(vertex, arcs)
        self.print()


if __name__ == '__main__':
    graph = OLGraph()
    graph.test_2()

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
十字链表是一种用于表示稀疏矩阵的数据结构,可以用于高效地存储和操作矩阵。下面是 Python 实现十字链表的示例代码: ```python class Node: def __init__(self, row, col, val): self.row = row self.col = col self.val = val self.right = None self.down = None class CrossList: def __init__(self, mat): self.r, self.c = len(mat), len(mat[0]) self.row_heads = [None] * self.r self.col_heads = [None] * self.c for i in range(self.r): for j in range(self.c): if mat[i][j] != 0: node = Node(i, j, mat[i][j]) if not self.row_heads[i]: self.row_heads[i] = node else: cur = self.row_heads[i] while cur.right: cur = cur.right cur.right = node if not self.col_heads[j]: self.col_heads[j] = node else: cur = self.col_heads[j] while cur.down: cur = cur.down cur.down = node def print_matrix(self): for i in range(self.r): cur = self.row_heads[i] for j in range(self.c): if cur and cur.col == j: print(cur.val, end=' ') cur = cur.right else: print(0, end=' ') print() def add(self, i, j, val): node = Node(i, j, val) if not self.row_heads[i]: self.row_heads[i] = node else: cur = self.row_heads[i] while cur.right and cur.right.col < j: cur = cur.right node.right = cur.right cur.right = node if not self.col_heads[j]: self.col_heads[j] = node else: cur = self.col_heads[j] while cur.down and cur.down.row < i: cur = cur.down node.down = cur.down cur.down = node def delete(self, i, j): if not self.row_heads[i] or not self.col_heads[j]: return if self.row_heads[i].col == j: self.row_heads[i] = self.row_heads[i].right else: cur = self.row_heads[i] while cur.right and cur.right.col != j: cur = cur.right if cur.right: cur.right = cur.right.right if self.col_heads[j].row == i: self.col_heads[j] = self.col_heads[j].down else: cur = self.col_heads[j] while cur.down and cur.down.row != i: cur = cur.down if cur.down: cur.down = cur.down.down ``` 这里定义了一个 `Node` 类来表示十字链表中的节点,包括行号、列号、值以及指向右侧和下方的指针。然后定义了一个 `CrossList` 类来表示整个十字链表,包括行头和列头指针数组。在初始化时,遍历输入矩阵中非零元素,创建相应的节点,并将其插入到行链表和列链表中。同时,`print_matrix` 方法可以输出原始矩阵,方便验证。`add` 方法可以添加一个新节点,`delete` 方法可以删除一个节点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值