CS61B 课程笔记(Lecture 27 Graphs)
CS61B 课程笔记(Lecture 27 Graphs)
1. 图的定义
- 图的基本组成:
- 一组节点(或称为顶点)。
- 一组零个或多个边,每条边连接两个节点。
- 图的特点:
- 任何结构都是一个有效的图。
- 所有的树都是图,但并不是所有的图都是树。
2. 图的类型
简单图与多重图
- 简单图(Simple Graph):
- 每对节点之间最多有一条边,且不允许有自环(即边连接节点自身)。
- 多重图(Multigraph):
- 允许节点之间有多条边,可能存在自环。
其他图的分类
- 无向图(Undirected Graph):
- 边的连接是双向的,例如边 (u, v) 意味着从节点 u 到节点 v 以及从节点 v 到节点 u。
- 有向图(Directed Graph):
- 边的连接是单向的,例如边 (u, v) 意味着从节点 u 到节点 v,而反向不一定存在。
- 无环图(Acyclic Graph):
- 图中不存在任何循环(从一个节点出发,经过若干边又回到该节点)。
- 循环图(Cyclic Graph):
- 存在从某个节点出发,经过一些边再回到起始节点的路径。
3. 图的问题
- 常见的图问题:
- s-t路径(s-t Path): 是否存在从节点 s 到节点 t 的路径?
- 连通性(Connectivity): 图是否是连通的,是否存在任意两个节点之间的路径?
- 双连通性(Biconnectivity): 是否存在一个节点的移除会使图不再连通?
- 最短 s-t 路径(Shortest s-t Path): 节点 s 和节点 t 之间的最短路径是什么?
- 循环检测(Cycle Detection): 图中是否存在循环?
- 欧拉巡游(Euler Tour): 是否存在一个循环使用每条边一次且仅一次?
- 哈密顿巡游(Hamilton Tour): 是否存在一个循环经过每个节点一次且仅一次?
- 可绘制性(Planarity): 能否在纸上绘制图形而不交叉边?
- 同构性(Isomorphism): 两个图是否同构(即是相同的图但以不同的形式表示)?
- 问题复杂性:
- 并不是所有图的问题都有清晰的复杂性界限,例如欧拉巡游问题是一个已解决的问题,而哈密顿巡游问题至今仍未找到有效解法,已知的最佳算法时间复杂度是指数级的。
4. 深度优先搜索
问题描述: 给定一个源节点 s 和一个目标节点 t,判断是否存在从 s 到 t 的路径。
初步尝试的代码:
1
2
3
4
5
6
7
8if (s == t):
return true;
for child in neighbors(s):
if isconnected(child, t):
return true;
return false;问题: 上述代码会导致无限循环。
改进方法: 使用“记住已访问节点”的方法:
1
2
3
4
5
6
7
8
9mark s // 记住已经访问过 s
if (s == t):
return true;
for child in unmarked_neighbors(s): // 忽略已标记的邻居
if isconnected(child, t):
return true;
return false;总结: 我们发展出了一种深度优先遍历的方法,类似于树的前序、中序和后序遍历。通过标记访问的节点,深入到每个子节点并访问其子节点,直到没有未标记的邻居为止。
5. 总结
本节内容介绍了图的基本概念、分类、常见问题以及深度优先搜索的基本思路。图论是计算机科学中非常重要的一个领域,其应用非常广泛,理解图的基本性质和算法是学习更复杂的图问题的基础。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Totoroの旅!
评论