Python数据结构之图的存储结构详解

Python数据结构之图的存储结构详解

什么是图

图是一种数据结构,用于表示不同对象之间的关系。在图中,对象通常表示为称为顶点的节点,而它们之间的关系称为边。边可以是无向的(没有方向)或有向的(有方向)。图分为有向图和无向图两种类型,根据边是否有方向来区别。

无向图

在无向图中,边没有方向,例如下图:

A -- B
|    |
C -- D

上面的图表示四个顶点 A,B,C 和 D 之间的关系,它们之间的边是无向的。例如,从顶点 A 到顶点 D 有两条路径: A -> B -> D 和 A -> C -> D。

有向图

在有向图中,边是有方向的,例如下图:

A -> B
|    |
v    v
C <- D

上图表示四个顶点 A,B,C 和 D 之间关系的有向图。它们之间的边是有方向的。例如,顶点 A 到顶点 D 之间的路径是 A -> C -> D。

图的存储结构

图的存储结构包含两种方式:邻接矩阵和邻接表。

邻接矩阵

邻接矩阵使用二维数组来表示图的顶点之间的关系。如果一个图有 N 个顶点,那么它的邻接矩阵就是 N x N 的方阵。数组中的每个元素表示一条边,如果两个顶点之间存在边,则它们之间的值为 1,否则为 0。

例如,下面的图可以用邻接矩阵来表示:

     A    B    C
A    0    1    1
B    1    0    1
C    1    1    0

上图中,每一行和每一列代表一个顶点,如果两个顶点之间有连线,则矩阵中对应位置的值为 1,否则为 0。

邻接表

邻接表使用链式数据结构来表示图的顶点之间的关系。邻接表的每个顶点都使用一个链表来存储与它相关的顶点。对于一个无向图,图中的每个顶点都与与它相邻的顶点相连。对于一个有向图,每个顶点有两个链表,一个链表存储指向该顶点的所有顶点,另一个链表存储该顶点可以到达的所有顶点。

例如,下面的图可以用邻接表来表示:

A -> B -> C
B -> A -> C
C -> A -> B

上图中,每一行代表一个顶点和与它相关的所有顶点的链表。在这个例子中,每个链表都只有一个节点,因为每个顶点只与另外两个顶点相连。

示例说明

使用邻接矩阵表示图

以下 Python 代码示例演示了如何使用邻接矩阵来表示一个无向图:

class Graph:
    def __init__(self, num_vertices):
        self.num_vertices = num_vertices
        self.adjacency_matrix = [[0] * num_vertices for _ in range(num_vertices)]

    def add_edge(self, i, j):
        self.adjacency_matrix[i][j] = 1
        self.adjacency_matrix[j][i] = 1

    def __repr__(self):
        return '\n'.join([' '.join([str(self.adjacency_matrix[i][j]) for j in range(self.num_vertices)]) for i in range(self.num_vertices)])

g = Graph(4)
g.add_edge(0, 1)
g.add_edge(0, 2)
g.add_edge(1, 2)
g.add_edge(2, 3)

print(g)

输出结果如下:

0 1 1 0
1 0 1 0
1 1 0 1
0 0 1 0

使用邻接表表示图

以下 Python 代码示例演示了如何使用邻接表来表示一个无向图:

class Node:
    def __init__(self, val):
        self.val = val
        self.neighbors = []

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

    def add_edge(self, node1, node2):
        if node1 not in self.adjacency_list:
            self.adjacency_list[node1] = Node(node1)
        if node2 not in self.adjacency_list:
            self.adjacency_list[node2] = Node(node2)
        self.adjacency_list[node1].neighbors.append(self.adjacency_list[node2])
        self.adjacency_list[node2].neighbors.append(self.adjacency_list[node1])

    def __repr__(self):
        res = ""
        for node in self.adjacency_list:
            res += str(node) + " -> "
            for neighbor in self.adjacency_list[node].neighbors:
                res += str(neighbor.val) + " "
            res += "\n"
        return res

g = Graph()
g.add_edge("A", "B")
g.add_edge("A", "C")
g.add_edge("B", "C")
g.add_edge("C", "D")

print(g)

输出结果如下:

A -> B C 
B -> A C 
C -> A B D 
D -> C 

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python数据结构之图的存储结构详解 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • JavaScript 双向链表操作实例分析【创建、增加、查找、删除等】

    下面就是 JavaScript 双向链表的完整攻略: 什么是双向链表 双向链表是一种链式数据结构,每个节点都包含两个指向前后节点的指针。相对于单向链表,双向链表可以在 O(1) 时间复杂度下进行前后节点的查找、插入、删除等操作。 双向链表的结构 Node: 双向链表的节点,包含三个属性 data: 存储节点的数据 prev: 指向前一个节点的指针 next:…

    other 2023年6月27日
    00
  • Mac 将mysql路径加入环境变量的方法

    以下是详细讲解 Mac 将 mysql 路径加入环境变量的方法的完整攻略。 1. 查看 Mysql 安装路径 首先需要查看一下你的 Mysql 安装路径。一般情况下,Mysql 的安装路径为 /usr/local/mysql。如果你使用 Homebrew 安装过 Mysql,则安装路径为 /usr/local/Cellar/mysql/{version_nu…

    other 2023年6月27日
    00
  • PHP可变变量学习小结

    PHP可变变量学习小结 在PHP中,可变变量是一种特殊的变量类型,它允许我们使用一个变量的值作为另一个变量的名称。这种灵活性可以在某些情况下非常有用,特别是当我们需要动态地创建和操作变量时。 使用可变变量 要使用可变变量,我们需要在变量名前面加上两个美元符号($$)。第一个美元符号表示我们正在引用一个变量,而第二个美元符号表示我们正在引用一个变量的值作为变量…

    other 2023年8月9日
    00
  • redis(开发与运维):39—内存之内存消耗分析

    Redis开发与运维:内存之内存消耗分析 在Redis中,内存是非常重要的资源。在使用Redis时,我们需要了解Redis如何使用内存,以便更好地管理内存资源。本攻略将介绍Redis中内存消耗的分析方法,并提供两个示例。 内存消耗分析方法 在Redis中,我们可以使用以下命令分析内存消耗: INFO memory命令:该命令用于获取Redis实例的内存使用情…

    other 2023年5月9日
    00
  • 慎升级! Win11更新KB5025239后遇 错误报告 TPM 2.0 / 蓝屏 等问题

    慎升级!Win11更新KB5025239后遇错误报告TPM 2.0 / 蓝屏等问题攻略 问题描述 最近,一些用户在升级Windows 11操作系统后遇到了一些问题,包括错误报告TPM 2.0和蓝屏等问题。这些问题可能与最新的更新KB5025239有关。下面是解决这些问题的攻略。 步骤一:备份重要数据 在进行任何操作之前,建议您首先备份重要的数据。这样可以确保…

    other 2023年8月3日
    00
  • iOS逆向工程使用dumpdecrypted工具给App脱壳

    首先,需要明确一下什么是脱壳。在iOS系统中,应用程序通常会被加密以保护其代码不被人轻易地窃取。而脱壳就是指利用一些工具将被加密的应用程序解密,从而让人们能够对其代码进行分析和修改。 其中,dumpdecrypted就是一款常用的用于iOS逆向工程的工具,它可以帮助我们将被加密的应用程序进行解密操作。 下面,我们来具体讲解一下如何使用dumpdecrypte…

    other 2023年6月26日
    00
  • springboot—mongodb

    Spring Boot + MongoDB Spring Boot是一种流行的Java框架,它提供了许多方便的功能来简化开发过程。MongoDB是一种流行NoSQL数据库,它提供了高性能和可扩展性。本文将介绍如何在Spring Boot中使用MongoDB,并提供两个示例说明。 步骤一:添加依赖 首先,我们需要在pom.xml文件中添加MongoDB的依赖:…

    other 2023年5月9日
    00
  • JavaScript实现的DOM树遍历方法详解【二叉DOM树、多叉DOM树】

    JavaScript实现的DOM树遍历方法详解【二叉DOM树、多叉DOM树】 DOM(Document Object Model)树是前端开发中非常重要的概念,我们通常都需要对DOM树进行遍历和操作,而JavaScript是我们常用的语言之一,我们可以使用JavaScript来实现DOM树的遍历和操作。本文将详细讲解JavaScript实现的DOM树遍历方法…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部