广度优先遍历

 

广度优先遍历(Breadth-First Search)

类似于对树的层序遍历

 

遍历规则为:首先访问初始点vi,并将其标记为已访问过,接着访问vi的所有未被访问过的邻接点,其访问次序可以任意,假定依次为vi1,vi2,...,vit,并均标记为已访问过,然后在按照vi1,vi2,...,vit的次序,访问每一个顶点的所有未被访问过的邻接点(次序任意),并均标记为已访问过,依次类推,直到图中所有和初始点vi有路径相通的顶点都被访问过为止。

 

在广度优先遍历中,先被访问的顶点,其邻接点亦先被访问,所以在算法的实现中需要使用一个队列,用来依次记住被访问过的顶点。从初始点vi出发广度优先遍历图的算法思想为:

(1)初始化队列Q;

(2)访问顶点vi,并将其标记为已访问,同时,顶点vi入队列Q;

(3)如果队列Q非空,重复执行步骤①、②和③:

    ① 出队列取得队首结点u;

    ② 取u第一个邻接点并赋予值给w;

    ③ 如果w存在,重复执行步骤a和b:

     a 如果w未被访问,则访问w,并将其标记为访问,同时顶点w入队列Q;

     b 取u的下一个邻接点并赋予值给w。

 

1.邻接矩阵存储结构下的广度优先遍历

void BFSTraverse_M( MGraph G, int i, void Visit(VertexType) ) { //从顶点vi出发非递归地广度优先遍历由邻接矩阵表示的图G int u,w; SqQueue Q; //队列Q InitQueue_Sq( Q, MAX_VERTEX_NUM, 10 ); //初始化队列Q if( !visited[i] ) { //顶点vi尚未被访问 visited[i] = true; //设置标记已访问 Visit( GetVex_M(G,i) ); //访问顶点vi EnQueue_Sq(Q,i); //顶点vi入队列Q while( !QueueEmpty_Sq(Q) ) { //队列不为空 DeQueue_Sq(Q,u); //队头元素出队并置为u //从u的第1个邻接顶点w起 for(w=FirstAdjVex_M(G,u);w>=0;w=NextAdjVex_M(G,u,w)) if( !visited[w] ) { //w为u的尚未访问的邻接顶点 visited[w] = true; //设置访问标记true(已访问) Visit( GetVex_M(G,w) ); //访问顶点w EnQueue_Sq(Q,w); //w入队列Q }//if }//while }//if }//BFSTraverse_M

2.邻接表存储结构下的广度优先遍历

void BFSTraverse_AL( ALGraph G, int i, void Visit(VertexType) ) { //从顶点vi出发非递归地广度优先遍历由邻接表表示的图G int u; ArcNode *p; //表结点指针类型 SqQueue Q; //队列Q InitQueue_Sq( Q, MAX_VERTEX_NUM, 10 ); //初始化队列Q if( !visited[i] ) { //顶点vi尚未被访问 visited[i] = true; //设置标记已访问 Visit( G.vertices[i].data ); //访问顶点vi EnQueue_Sq(Q,i); //顶点vi入队列Q while( !QueueEmpty_Sq(Q) ) { //队列不为空 DeQueue_Sq(Q,u); //队头元素出队并置为u for(p=G.vertices[u].firstarc;p;p=p->next) if( !visited[p->adjvex] ) { visited[p->adjvex] = true; //设置访问标记true(已访问) Visit( G.vertices[p->adjvex].data ); //访问该邻接顶点 EnQueue_Sq(Q,p->adjvex); //该邻接顶点序号入队 }//if }//while }//if }//BFSTraverse_AL

你可能感兴趣的:(数据结构,算法,存储,search)