广度优先搜索
广度优先搜索
广度优先搜索算法
换句话说,广度优先搜索遍历图的过程是以
无向图的广度优先搜索
下面以

- 第
1 步:访问A 。 - 第
2 步:依次访问C 、D、F。在访问了A 之后,接下来访问A 的邻接点。前面已经说过,在本文实现中,顶点ABCDEFG 按照顺序存储的,C 在"D 和F" 的前面,因此,先访问C 。再访问完C 之后,再依次访问D,F 。 - 第
3 步:依次访问B,G 。在第2 步访问完C,D,F 之后,再依次访问它们的邻接点。首先访问C 的邻接点B ,再访问F 的邻接点G 。 - 第
4 步:访问E 。在第3 步访问完B,G 之后,再依次访问它们的邻接点。只有G 有邻接点E ,因此访问G 的邻接点E 。
因此访问顺序是:A -> C -> D -> F -> B -> G -> E
有向图的广度优先搜索
下面以

- 第
1 步:访问A 。 - 第
2 步:访问B 。 - 第
3 步:依次访问C,E,F 。在访问了B 之后,接下来访问B 的出边的另一个顶点,即C,E,F 。前面已经说过,在本文实现中,顶点ABCDEFG 按照顺序存储的,因此会先访问C ,再依次访问E,F 。 - 第
4 步:依次访问D,G 。在访问完C,E,F 之后,再依次访问它们的出边的另一个顶点。还是按照C,E,F 的顺序访问,C 的已经全部访问过了,那么就只剩下E,F ;先访问E 的邻接点D ,再访问F 的邻接点G 。
因此访问顺序是:A -> B -> C -> E -> F -> D -> G
广度优先遍历
图的广度优先遍历基于广度优先搜索
下图

广度优先搜索是一种分层的搜索过程,它类似于树的层次遍历。从图中可以看出,搜索每向前走一步可能访问一批顶点,不像深度优先搜索那样有往回退的情况,因此,广度优先遍历不是一个递归的过程,其算法也不是递归的。为了实现逐层访问,算法中使用了一个队列,以记录刚才访问过的上一层和本层顶点,以便于向下一层访问。从指定的结点
(1)访问结点
代码实现
// 广度优先遍历的算法
template<class vertexType, class arcType>void Graph <vertexType, arcType> ::
BFTraverse (void visit( vertexType v )) {
int i, n = NumberOfVertexes() ;//取图的顶点个数
int * visited = new int [n]; //定义访问标记数组 visited
for ( i = 0; i < n; i++ )
visited [i] = 0; //访问标记数组 visited 初始化
for ( i = 0; i < n; i++ ) //对图中的每一个顶点进行判断
if (!visited [i]) BFS (i, visited, visit);
delete [ ] visited; //释放 visited
}
// 广度优先搜索的算法
template<class vertexType, class arcType> void Graph <vertexType, arcType> ::
BFS (const int v, int visited [ ], void visit( vertexType v )) {
linkqueue <int> q; //定义队列q
visit( GetValue (v)); //访问顶点 v
visited[v] = 1; //顶点 v 作已访问标记
q.EnQueue (v); //顶点 v 进队列q
while ( !q.IsEmpty ( ) ) {
v = q.DeQueue ( ); //否则, 队头元素出队列
int w = GetFirstNeighbor (v);
while ( w != -1 ) { //若邻接顶点 w 存在
if ( !visited[w] ) { //若该邻接顶点未访问过
visit( GetValue (w)); //访问顶点 w
visited[w] = 1; //顶点 w 作已访问标记
q.EnQueue (w); //顶点 w 进队列q
}
w = GetNextNeighbor (v, w);
} //重复检测 v 的所有邻接顶点
} //外层循环,判队列空否
}
在图的广度优先遍历算法中,图中每一个顶点需进队列一次且仅进队列一次,而在遍历过程中是通过边来搜索邻接点的。所以,图的广度优先遍历算法的时间复杂度和图的深度优先遍历算法的时间复杂度类似,如果使用邻接表表示图,则其时间复杂度为