本次笔记内容:
6.2.1 图的遍历 - DFS
6.2.2 图的遍历 - BFS
6.2.3 图的遍历 - 为什么需要两种遍历
6.2.4 图的遍历 - 图连不通怎么办?

深度优先搜索(Depth First Search, DFS)

深度优先搜索在无路可走时会进行“原路返回”,对于堆栈入栈出栈的操作。

伪码描述如下:

void DFS (Vertex V)
{
	visited[V] = true;
	for (V的每个邻接点W)
		if (!visited[W])
			DFS(W);
}

类似于树的先序遍历(即DFS是树的先序遍历的推广)。

若有N个顶点、E条边,时间复杂度是:

  • 用邻接表存储图,有O(N+E)
  • 用邻接矩阵存储图,有O(N^2)

广度优先搜索(Breadth First Search, BFS)

广度优先实际上时树的层序遍历的推广,操作对应于队列的出队入队行为。

伪码描述如下:

void BFS (Vertex V)
{
	visited[V] = true;
	Enqueue(V, Q);	// 入队
	while(!IsEmpty(Q)) {
		V = Dequeue(Q);
		for (V的每个邻接点W) 
			if (!visited[W]) {
				visited[W] = true;
				Enqueue(W, Q);
			}
	}
}

若有N个顶点、E条边,时间复杂度是:

  • 用邻接表存储图,有O(N+E)
  • 用邻接矩阵存储图,有O(N^2)

为什么需要两种遍历?

【数据结构笔记21】图的遍历,DFS与BFS,连通图_数据结构

如上图,大侠想要到达绿色出口,使用DFS可能经历许多格子。

【数据结构笔记21】图的遍历,DFS与BFS,连通图_数据结构_02

如上图,大侠想要到达绿色出口,使用BFS经历较少格子。

但是,如果问题不同(比如换到其他位置),DFS可能更好用。

图不连通怎么办?

连通与路径的相关定义

通用定义与无向图
  • 连通:如果从V到W存在一条(无向)路径,则称V和W是连通的。
  • 路径:V到W的路径是一系列顶点{V,v_1,v_2,…,v_n,W}的集合,其中任一对相邻的顶点间都有图中的边。
  • 路径的长度:路径中的边数(如果带权,则是所有边的权重和)。如果V到W之间的所有顶点都不同,则称为简单路径
  • 回路:起点等于终点的路径。
  • 连通图:图中任意两点连通。
  • 连通分量:无向图的极大连通子图:
    • 极大顶点数:再加1个顶点就不连通了;
    • 极大边数:包含子图中所有顶点相连的所有边。

【数据结构笔记21】图的遍历,DFS与BFS,连通图_数据结构_03

如上图,左边两个是G的连通分量。

对于有向图
  • 强连通:有向图中顶点V和W之间存在双向路径,则称V和W是强连通的;
  • 强连通图:有向图中任意两顶点均强连通;
  • 强连通分量:有向图的极大连通子图。

【数据结构笔记21】图的遍历,DFS与BFS,连通图_数据结构_04

如上图,G有两个强连通分量。

而弱连通,即非强连通,将有向图改为无向图后也是连通的。

【数据结构笔记21】图的遍历,DFS与BFS,连通图_数据结构_05

如上图所示,如果想要访问图中所有顶点,可采用DFS或BFS辅助。