Traverse
通常有两种方式:
- 广度优先搜索(BFS,Breadth-First-Search)
- 深度优先搜索(DFS,Depth-First-Search)
1 BFS
1.1 Explanation
这是一种层次遍历的方法,可以通过队列这种数据结构来实现,每次向前走一步访问新的一批顶点:
- 首先我们需要一个标记数组
visited[MAX_VEX]
以及一个辅助队列queue
- 然后我们可以按顶点标号顺序开始访问,先将标号第一个顶点入队,以这个顶点为起点开始进行广度优先搜索:按顺序将这个顶点的未访问的邻接顶点入队后,将这个顶点出队,重复这个操作直到队列为空为止,即完成以这个顶点为起点的广度优先搜素
- 继续对下一个顶点进行广度优先搜索,首先判断这个顶点是否已经被访问过,如果没有,进行广度优先搜索,如果已经访问,则继续看下一个顶点直到最后一个顶点已经被访问过了(考虑图可能不是连通图,含有多个连通分量,因此我们必须对每个顶点都看一次,因为即使只有一个顶点也可能会是一个连通分量)
最终,我们便完成了广度优先搜索通过广度优先搜索可以找到从某个顶点出发到达其他顶点的最短路径(即单源最短路径)
1.2 Performance
根据存储结构不同,广度优先搜索的性能不同:
- 邻接表: O ( ∣ V ∣ + ∣ E ∣ ) O(|V|+|E|) O(∣V∣+∣E∣),即每个顶点访问一次,每条边至少访问一次
- 邻接矩阵: O ( ∣ V ∣ 2 ) O(|V|^{2}) O(∣V∣2),即邻接矩阵遍历的复杂度
2. DFS
2.1 Definition
- 同样还需要一个标记数组
- 按顶点序号入栈,将标号第一个顶点入栈,然后继续找这个顶点标号最前的邻接顶点入栈,重复这个操作直到当前顶点的邻接顶点都已经访问过为止,这时逐步退栈,对栈顶顶点重复上述操作,直到栈退至空,即完成以第一个顶点的深度优先搜索
- 同样还需要对第二个顶点继续做以上操作,直到所有顶点已经访问为止
最终我们便完成了图的深度优先搜索
2.2 Performance
同样根据存储结构不同:
- 邻接链表: O ( ∣ V ∣ + ∣ E ∣ ) O(|V|+|E|) O(∣V∣+∣E∣)
- 邻接矩阵: O ( ∣ V ∣ 2 ) O(|V|^{2}) O(∣V∣2)