当前位置: 首页 > news >正文

数据结构之图结构

数据结构之图结构

    • 前言
    • 一、图结构的基本概念
      • 1.1 图的定义
      • 1.2 图的相关术语
    • 二、图的存储方式
      • 2.1 邻接矩阵
      • 2.2 邻接表
    • 三、图的遍历算法
      • 3.1 深度优先搜索(DFS)
      • 3.2 广度优先搜索(BFS)
    • 四、图结构应用场景
      • 4.1 社交网络分析
      • 4.2 路径规划
      • 4.3 任务调度
      • 4.4 网络通信
    • 总结

前言

图结构是处理复杂关系数据的关键工具,从社交网络中的人际关系分析,到交通网络的路径规划,再到搜索引擎的网页链接分析,都发挥着不可或缺的作用。本文我将初步探讨图结构的基本概念、存储方式、遍历算法以及实际应用场景,并结合代码示例,带你初步进入这一重要的数据结构。

一、图结构的基本概念

1.1 图的定义

图(Graph)是由顶点(Vertex)集合 V V V边(Edge)集合 E E E 组成的二元组,记为 G = ( V , E ) G=(V, E) G=(V,E)。顶点用于表示数据对象,边则表示顶点之间的关系。根据边是否有方向,图可分为无向图有向图

  • 无向图:边没有方向,例如表示城市之间的道路连接,道路是双向通行的。在无向图中,若顶点 u u u v v v 之间有边相连,则这条边可表示为 ( u , v ) (u, v) (u,v),且 ( u , v ) (u, v) (u,v) ( v , u ) (v, u) (v,u) 表示同一条边。
    无向图

  • 有向图:边具有方向,比如社交网络中用户之间的关注关系,关注是单向的。在有向图中,从顶点 u u u 到顶点 v v v 的边表示为 ⟨ u , v ⟩ \langle u, v \rangle u,v,它与 ⟨ v , u ⟩ \langle v, u \rangle v,u 是不同的边。

  • 有向图

1.2 图的相关术语

  • 顶点的度:在无向图中,顶点的度是指与该顶点相连的边的数量;在有向图中,顶点的度分为入度和出度,入度是指以该顶点为终点的边的数量,出度是指以该顶点为起点的边的数量。

  • 边的权值:有些图的边会附带一个数值,称为权值,用于表示顶点之间关系的某种度量,如距离、成本等。这样的图称为带权图。

  • 路径:由一系列顶点和连接这些顶点的边组成的序列。如果路径的起点和终点相同,则称为回路或环。

  • 连通图:在无向图中,如果任意两个顶点之间都存在路径,则称该图为连通图;在有向图中,如果对于任意两个顶点 u u u v v v,都存在从 u u u v v v 和从 v v v u u u 的路径,则称该图为强连通图。

二、图的存储方式

2.1 邻接矩阵

邻接矩阵是一种用二维数组来表示图的存储方式。对于具有 n n n 个顶点的图,其邻接矩阵是一个 n × n n \times n n×n 的矩阵 A A A。在无向图中,如果顶点 i i i j j j 之间有边相连,则 A [ i ] [ j ] = A [ j ] [ i ] = 1 A[i][j] = A[j][i] = 1 A[i][j]=A[j][i]=1;否则 A [ i ] [ j ] = A [ j ] [ i ] = 0 A[i][j] = A[j][i] = 0 A[i][j]=A[j][i]=0。在带权图中,若顶点 i i i j j j 之间有边相连,且边的权值为 w w w,则 A [ i ] [ j ] = A [ j ] [ i ] = w A[i][j] = A[j][i] = w A[i][j]=A[j][i]=w;若没有边相连,通常用一个特殊值(如无穷大)表示。

# 无向图的邻接矩阵示例
graph = [[0, 1, 1, 0],[1, 0, 0, 1],[1, 0, 0, 1],[0, 1, 1, 0]
]

邻接矩阵的优点是实现简单,便于判断两个顶点之间是否有边相连,并且可以快速获取顶点的度;缺点是空间复杂度较高,为 O ( n 2 ) O(n^2) O(n2),对于边数较少的稀疏图,会造成大量的空间浪费。

2.2 邻接表

邻接表是一种链式存储结构,它为图中的每个顶点建立一个单链表,链表中的节点表示与该顶点相邻的顶点及其相关信息(如边的权值)。在无向图中,每个顶点的链表中存储其所有相邻顶点;在有向图中,每个顶点的链表存储以该顶点为起点的所有边的终点顶点。

# 无向图的邻接表示例
graph = {0: [1, 2],1: [0, 3],2: [0, 3],3: [1, 2]
}

邻接表的优点是空间效率高,适用于存储稀疏图,空间复杂度为 O ( n + e ) O(n + e) O(n+e) n n n 为顶点数, e e e 为边数);缺点是判断两个顶点之间是否有边相连需要遍历链表,时间复杂度较高,为 O ( d ) O(d) O(d) d d d 为顶点的度)。

三、图的遍历算法

3.1 深度优先搜索(DFS)

深度优先搜索类似于树的先序遍历,它从图的某个顶点出发,沿着一条路径尽可能深地访问顶点,直到无法继续,然后回溯到上一个顶点,继续探索其他路径,直到访问完所有可达顶点。DFS 可以使用递归或栈来实现。

# 使用递归实现无向图的DFS
def dfs(graph, vertex, visited):visited.add(vertex)print(vertex)for neighbor in graph[vertex]:if neighbor not in visited:dfs(graph, neighbor, visited)graph = {0: [1, 2],1: [0, 3],2: [0, 3],3: [1, 2]
}
visited = set()
dfs(graph, 0, visited)

DFS 的时间复杂度在邻接矩阵表示下为 O ( n 2 ) O(n^2) O(n2),在邻接表表示下为 O ( n + e ) O(n + e) O(n+e)。它常用于寻找图中的连通分量、拓扑排序等场景。

3.2 广度优先搜索(BFS)

广度优先搜索类似于树的层序遍历,它从图的某个顶点出发,先访问该顶点的所有相邻顶点,然后再依次访问这些相邻顶点的未访问过的相邻顶点,以此类推,直到访问完所有可达顶点。BFS 通常使用队列来实现。

# 无向图的BFS实现
from collections import dequedef bfs(graph, start):visited = set()queue = deque([start])visited.add(start)while queue:vertex = queue.popleft()print(vertex)for neighbor in graph[vertex]:if neighbor not in visited:queue.append(neighbor)visited.add(neighbor)graph = {0: [1, 2],1: [0, 3],2: [0, 3],3: [1, 2]
}
bfs(graph, 0)

BFS 的时间复杂度同样在邻接矩阵表示下为 O ( n 2 ) O(n^2) O(n2),在邻接表表示下为 O ( n + e ) O(n + e) O(n+e)。它常用于寻找最短路径(在无权图中)、最小生成树等问题。

四、图结构应用场景

4.1 社交网络分析

在社交网络中,用户可以看作图的顶点,用户之间的关注、好友关系等可以看作边。通过图结构可以分析用户的社交圈子、影响力,例如找出某个用户的所有好友及其好友的好友,或者计算用户之间的最短社交距离。

4.2 路径规划

在交通网络中,城市或地点是顶点,道路是边,边的权值可以是距离、通行时间等。利用图的最短路径算法(如迪杰斯特拉算法、弗洛伊德算法),可以实现导航系统中的路径规划功能,帮助用户找到从起点到终点的最优路线。

4.3 任务调度

在项目管理中,任务可以看作顶点,任务之间的依赖关系看作边。通过图的拓扑排序算法,可以确定任务的执行顺序,确保在执行某个任务之前,其依赖的任务已经完成,从而合理安排项目进度。

4.4 网络通信

在计算机网络中,节点和连接可以用图来表示。通过图的分析可以优化网络拓扑结构,检测网络中的故障节点或链路,提高网络的可靠性和效率。

总结

图结构作为一种强大的数据结构,能够有效表示和处理复杂的关系型数据。从基本概念到存储方式,从遍历算法到实际应用,图结构涵盖了丰富的知识和广泛的应用场景。掌握图结构的相关知识,不仅有助解决算法中的复杂问题,还能在实际软件开发、数据分析等领域发挥重要作用。本文只是初始图结构,最小生成树最短路径等问题篇幅有限,感兴趣的请进我主页算法专题查看。

That’s all, thanks for reading!
觉得有用就点个赞、收进收藏夹吧!关注我,获取更多干货~

http://www.xdnf.cn/news/639415.html

相关文章:

  • vllm 2080TI ubuntu环境安装
  • PySide6 GUI 学习笔记——常用类及控件使用方法(常用类图标QIcon)
  • 【大模型应用开发】Qwen2.5-VL-3B识别视频
  • boost之preprocessor
  • 人工智能(AI)技术包括哪些技术
  • TCP 协议的相关特性
  • How to balance work and personal life?
  • 前端流行框架Vue3教程:28. Vue应用
  • PostgreSQL windows安装
  • Vue3编译器:静态提升原理
  • VBox共享文件夹
  • 2025一带一路暨金砖国家技能发展与技术创新大赛第三届企业信息系统安全赛项
  • Go语言--语法基础5--基本数据类型--循环语句
  • [ACTF新生赛2020]easyre
  • Bolt.new:重塑 Web 开发格局的 AI 利器
  • MFC:获取所有打印机的名称(打印机模块-2)
  • 【Siggraph Asia 2023】低光增强Diffusion-Low-Light-main(引入diffusion与DWT) -- part1论文精读
  • AutoGen SelectorGroupChat 示例:社会热搜话题事件榜单
  • 成功解决ImportError: cannot import name ‘DTensor‘ from ‘torch.distributed.tensor‘
  • 选择排序算法研究
  • 【NIPS 2024】Towards Robust Multimodal Sentiment Analysis with Incomplete Data
  • C++异步(1)
  • [Protobuf] 快速上手:安全高效的序列化指南
  • SymAgent:一种用于知识图谱复杂推理的神经符号自学Agent框架
  • Oracle中的[行转列]与[列转行]
  • 【目标检测】【医学图像目标检测】BGF-YOLO:脑肿瘤检测的多尺度注意力特征融合
  • 【linux】systemctl基本语法
  • 康佳Java开发面试题及参考答案
  • 前端vue3实现图片懒加载
  • 【LCEL深度解析】LangChain表达式语言的工程化实践指南