CS61B 课程笔记(Lecture 28 Graph Traversals)
CS61B 课程笔记(Lecture 28 Graph Traversals)
图遍历概述
- 深度优先搜索(DFS): 从起始节点开始,沿着一条路径深入,直到无法继续为止,然后回溯。
- 广度优先搜索(BFS): 从起始节点开始,先访问所有直接相连的节点,然后逐层向外扩展,访问下层节点。
广度优先搜索(BFS)
BFS按照层级访问图的节点,具体步骤如下:
伪代码
1 | 1. 初始化一个空队列(fringe) |
- fringe: 存储待访问节点的队列。
- edgeTo: 记录如何到达每个节点。
- distTo: 记录从起始顶点到每个节点的距离(假设每条边的距离为 1)。
BFS的特点
- 在BFS中,节点一被添加到队列就立即标记。
- BFS适用于求解最短路径问题。
深度优先搜索(DFS)
DFS的实现有递归和迭代两种方式:
伪代码(迭代)
1 | 1. 初始化一个空栈(fringe) |
图的表示方法
邻接列表(Adjacency List):
- 使用一个数组,数组的每个位置代表一个顶点,位置中存储该顶点的所有邻居。
- 是实践中最常用的表示方法。
示例:
1
2
3
4
5
6int[][] adjList = {
{1, 2}, // 节点 0 的邻居
{0, 3}, // 节点 1 的邻居
{0}, // 节点 2 的邻居
{1} // 节点 3 的邻居
};邻接矩阵(Adjacency Matrix):
- 使用一个二维数组,大小为 (\(N \times N\)),$N \(为顶点数,数组的 (\)i, j$) 项为 true 表示有从 $i \(到\)j$ 的边,否则为 false。
示例:
1
2
3
4
5
6| | 0 | 1 | 2 | 3 |
|---|---|---|---|---|
| 0 | 0 | 1 | 1 | 0 |
| 1 | 1 | 0 | 0 | 1 |
| 2 | 1 | 0 | 0 | 0 |
| 3 | 0 | 1 | 0 | 0 |边集合(Edge Collection):
- 使用 HashSet 存储边,每条边由一对整数表示。
效率分析
- 邻接列表的遍历: (\(O(V + E)\)),其中 (\(V\)) 是顶点数,(\(E\)) 是边数。
- 邻接矩阵的遍历: (\(O(V^2)\)),因为每次都要检查每一对顶点是否相邻。
操作 | 邻接列表 | 邻接矩阵 |
---|---|---|
查询边 (u, v) | \(O(E)\) | \(O(1)\) |
获取邻居 | \(O(E)\) | \(O(V)\) |
计算顶点数量 | \(O(1)\) | \(O(1)\) |
计算边数量 | \(O(1)\) | \(O(1)\) |
总结
- DFS和BFS: 这两种遍历方法可以用于图的各种算法,选择合适的遍历方法对解决问题至关重要。
- 图的实现: 选择合适的数据结构会影响程序的运行效率和内存使用情况。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Totoroの旅!
评论