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

图论入门与邻接表详解


📘 图论入门与邻接表详解

—— 零基础也能看懂的图论学习笔记


一、什么是图论?

图论(Graph Theory) 是数学和计算机科学中的一个重要分支,研究“图”这种结构。

图(Graph) ≠ 柱状图/折线图
它是由 顶点(Vertex/Node)边(Edge) 组成的结构,用来表示对象之间的关系。

🌟 常见应用场景:

  • 社交网络:人是顶点,朋友关系是边
  • 地图导航:城市是顶点,道路是边
  • 课程依赖:课程是顶点,先修关系是边
  • 网页链接:网页是顶点,超链接是边

二、图的基本组成

概念说明
顶点(Vertex)表示一个对象,如人、城市、网页
边(Edge)表示两个顶点之间的连接或关系
图 G = (V, E)V 是顶点集合,E 是边集合

举例:

A —— B —— C
  • 顶点:A, B, C
  • 边:A-B, B-C

三、图的类型

类型说明示例
无向图边没有方向,A—B 等价于 B—A朋友关系
有向图边有方向,A→B 不一定可逆网页链接、课程依赖
加权图每条边有“权重”(如距离、成本)导航系统中的道路长度
简单图无自环、无重复边大多数算法题
多重图允许重复边或自环少见

四、基本术语

术语含义
度(Degree)一个顶点连接的边数(有向图分入度/出度)
路径(Path)从一个顶点到另一个顶点经过的边序列
环(Cycle)起点和终点相同的路径
连通图任意两点都有路径(无向图)
强连通任意两点可互相到达(有向图)
树(Tree)无环的连通无向图

五、图的存储方式

有两种主流方式:

1. 邻接矩阵(Adjacency Matrix)

  • 用二维数组 matrix[i][j] 表示是否有边
  • 空间复杂度:O(V²)
  • 适合稠密图

2. ✅ 邻接表(Adjacency List) ← 推荐初学者掌握


六、邻接表详解(重点!)

1. 什么是邻接表?

每个顶点维护一个列表,记录它连接的所有邻居。

📌 本质:“谁和我相连”

2. 如何建邻接表?(三步法)

✅ 步骤 1:初始化
# 顶点编号 0 ~ n-1(连续整数)
n = 5
g = [[] for _ in range(n)]  # g[i] 是顶点 i 的邻居列表

⚠️ 错误写法:g = [[]] * n → 所有子列表共享引用!
✅ 正确写法:g = [[] for _ in range(n)]

✅ 步骤 2:添加边
无向图(双向)
u, v = 1, 2
g[u].append(v)
g[v].append(u)
有向图(单向)
u, v = 1, 2  # u → v
g[u].append(v)
# 不加反向边
✅ 步骤 3:处理重复边(可选)
seen = set()
for a, b in edges:if (a, b) not in seen:seen.add((a, b))g[b].append(a)  # 例如课程依赖

3. 邻接表示例

示例 1:无向图
A — B — C
g = {'A': ['B'],'B': ['A', 'C'],'C': ['B']
}
示例 2:有向图(课程依赖)
prerequisites = [[1,0], [2,1]]  # 0→1, 1→2
g = [[1], [2], []]

图:0 → 1 → 2


4. 如何“读”邻接表?

给你一个邻接表,如何还原图?

g = [[1], [2], [0]]
  1. 顶点:0, 1, 2
  2. 读每行:
    • 0 → 1
    • 1 → 2
    • 2 → 0
  3. 画图 → 发现环:0→1→2→0

📌 判断有向/无向:

  • 对称 → 无向
  • 不对称 → 有向

5. 邻接表 vs 邻接矩阵

对比项邻接表邻接矩阵
空间O(V + E)O(V²)
适合稀疏图稠密图
查边O(度)O(1)
遍历邻居

推荐使用邻接表:大多数算法题中图是稀疏的。


七、邻接表 + 常见算法

1. BFS(广度优先搜索)

from collections import dequedef bfs(start, g):visited = [False] * len(g)queue = deque([start])order = []while queue:node = queue.popleft()if not visited[node]:visited[node] = Trueorder.append(node)for neighbor in g[node]:if not visited[neighbor]:queue.append(neighbor)return order

用途:最短路径(无权图)、层序遍历


2. DFS(深度优先搜索)

def dfs(node, g, visited, order):visited[node] = Trueorder.append(node)for neighbor in g[node]:if not visited[neighbor]:dfs(neighbor, g, visited, order)

用途:检测环、拓扑排序、连通性


八、经典应用:课程表问题(拓扑排序)

判断是否能完成所有课程(即图是否有环):

def canFinish(numCourses, prerequisites):g = [[] for _ in range(numCourses)]for a, b in prerequisites:g[b].append(a)  # b → acolors = [0] * numCourses  # 0:未访问, 1:访问中, 2:已完成def dfs(x):colors[x] = 1for y in g[x]:if colors[y] == 1:return True  # 发现环if colors[y] == 0 and dfs(y):return Truecolors[x] = 2return Falsefor i in range(numCourses):if colors[i] == 0 and dfs(i):return False  # 有环return True

📌 核心:用 colors 标记状态,g 存图,dfs 检测环。


九、学习建议

  1. 从画图开始:先画几个小图,练习 BFS/DFS 手动遍历
  2. 动手实现:用 Python 写邻接表 + BFS/DFS
  3. 刷题巩固
    • LeetCode 200. 岛屿数量(DFS/BFS)
    • LeetCode 207. 课程表(拓扑排序)
    • LeetCode 133. 克隆图
  4. 理解本质:图是“关系”的抽象,邻接表是“谁连谁”的记录

十、总结口诀

🔑 邻接表三步走

  1. g = [[] for _ in range(n)]
  2. 遍历边,取出 u, v
  3. 加边:
    • 无向:g[u].append(v) + g[v].append(u)
    • 有向:g[u].append(v)

🔑 图论一句话
顶点是对象,边是关系,邻接表是存储,BFS/DFS 是遍历工具。


http://www.dtcms.com/a/351472.html

相关文章:

  • 代码随想录Day62:图论(Floyd 算法精讲、A * 算法精讲、最短路算法总结、图论总结)
  • ElementUI之菜单(Menu)使用
  • 美团购物车小球动画效果
  • Docker Compose 使用指南 - 1Panel 版
  • 国产化芯片ZCC3790--同步升降压控制器的全新选择, 替代LT3790
  • 第17章|PowerShell 安全警报——高分学习笔记(运维实战向)
  • Tableau Server高危漏洞允许攻击者上传任意恶意文件
  • 数据库云平台:提升运维效率与降低成本的有效工具
  • 【Ubuntu系统实战】一站式部署与管理MySQL、MongoDB、Redis三大数据库
  • WPS 智能文档,5分钟上手!
  • React学习教程,从入门到精通, React教程:构建你的第一个 React 应用(1)
  • 电力时序预测相关论文
  • 物流配送路径规划项目方案
  • yggjs_rbutton React按钮组件v1.0.0 最佳实践指南
  • 从陪聊到客服,声网如何支撑AI实时交互?
  • Rust 登堂 之 函数式编程(三)
  • 面试之JVM
  • CentOS 7 服务器初始化:从 0 到 1 的安全高效配置指南
  • 使用 flutter_tts 的配置项
  • C# 13 中的新增功能实操
  • 深入了解AWS Auto Scaling
  • OpenAI API Python实战教程:如何稳定获取结构化 JSON 输出(简易/复杂 双示例)
  • Nginx Ubuntu vs CentOS 常用命令对照表---详解笔记
  • AR技术引领航空制造迈向智能化新时代
  • Java标识符命名规则与规范
  • 32.Attention-注意力机制
  • 【算法--链表题2】19.删除链表的倒数第 N 个节点:通俗详解
  • A股大盘数据-20250826 分析
  • Java大厂面试实战:从Spring Boot到微服务架构的全链路技术剖析
  • 英伟达jetson开发板Ubuntu系统配置显示屏系统脱离手动输入指令自动编译执行操作