「这是我参与2022首次更文挑战的第27天,活动详情查看:2022首次更文挑战」
上篇简单介绍一下图的数据结构的几种构成方式,图跟树一样都是可以进行遍历的,今天就来简单介绍一下图的两种遍历方式 —— 广度优先 && 深度优先
图的遍历:从图的任一节点为起始点出发,通过某种搜索方式,访问图中的所有节点
图之广度优先(BFS)
- 别称:宽度优先搜索
- 搜索过程:
- 任一节点为源点出发
- 一次性访问邻接点中未被访问过的节点
- 依次以这些已访问过的邻接点为源点出发,一层一层地去继续访问未被访问访问过的节点
- 广度优先遍历是按照广度优先搜索的方式对图进行遍历
- 先被访问的节点,它的邻接点会被优先访问到(可通过队列来实现先进先出的访问顺序)
- 算法步骤:
- 初始化【 所有节点的状态设置为未被访问 + 空队列 】
- 任一节点(v)为起始点【 访问 + 标记为已被访问 + v 入队 】
- 队列非空——继续;队列为空——结束
- 队头元素(v)出队 -> v 的所有未被访问的邻接点【 依次访问 + 标记为已被访问 + 邻接点入队 】-> 继续上一步
- 基于邻接矩阵的广度优先遍历
- 每个节点的邻接点时间复杂度O(n) + 总时间复杂度O(n^2)
- 辅助队列【 每个节点入队一次 + 空间复杂度O(n) 】
- 基于邻接表的广度优先遍历
- 查找邻接点的时间复杂度O(e) + 初始化O(n) => 总的时间复杂度O(n+e)
- 同上
图之深度优先(DFS)
- 搜索过程:
- 找到一条路径 -> 沿着路径一直搜索 -> 至无法搜索时 -> 回退到刚刚访问的节点
- 深度优先遍历时按照深度优先搜索的方式对图进行遍历
- 后被访问的节点,它的邻接点会被优先访问到(可通过栈来实现先进后出的访问顺序——递归是通过栈实现的)
- 算法步骤:
- 初始化【 所有节点的状态设置为未被访问 】
- 任一节点(v)为起始点【 访问 + 标记为已被访问 】
- 一次检查节点的所有邻接点(w)【 w 未被访问 -> 以 w 为起始点 -> 继续遍历(通过递归调用上一步) 】
- 基于邻接矩阵的深度优先遍历
- 每个节点的邻接点时间复杂度O(n) + 总时间复杂度O(n^2)
- 通过递归栈【 空间复杂度O(n) 】
- 基于邻接表的深度优先遍历
- 查找邻接点的时间复杂度O(e) + 初始化O(n) => 总的时间复杂度O(n+e)
- 同上
注
- 图的邻接矩阵是唯一的
- 基于邻接矩阵的广度优先遍历和深度优先遍历,得到的序列也是唯一的
- 图的邻接表是不唯一的
- 基于邻接表的广度优先遍历和深度优先遍历,得到的序列也不是唯一的