1.算法思想
(1)从图中的某个初始点 v0 出发,首先访问初始点 v0。
(2)接着访问该顶点的所有未访问过的邻接点 v01 v02 v03 ……v0n。
(3)然后再选择 v01 v02 v03 ……v0n,访问它们的未被访问的邻接点,v010 v011 v012……v01n。
(4)直到所有与初始顶点 v 联通的顶点都被访问。
其实和树的层序遍历很像,都用到了队列的思想。
以邻接表储结构,在运用广度优先遍历时需要引入一个队列SeQuence,用来存储和输出遍历数据,visiteBFS[]记录访问状态(v 是初始点)。
2.代码实现
图的结构定义
typedef struct eNode {
int adjVer; //该边的邻接点编号
int weight; //该边的的信息,如权值
struct eNode* nextEdge; //指向下一条边的指针
}EdgeNode; //别名,边结点的类型
typedef struct vNode {
EdgeNode* firstEdge; //指向第一个边结点
}VNode; //别名,邻接表的头结点类型
typedef struct list {
int n; //顶点个数
int e; //边数
VNode adjList[MAXV]; //邻接表的头结点数组
}ListGraph; //别名,完整的图邻接表类型
函数
//广度优先遍历
void BFS(ListGraph* LG, int v) {
int ver; //定义出队顶点
EdgeNode* p;
SqQueue* sq; //定义指针
initQueue(sq); //初始化队列
int visitedBFS[MAXV] = { 0 }; //初始化访问标记数组
enQueue(sq, v); //初始点进队
printf("%2d", v);
visitedBFS[v] = 1; //打印并标记要出队顶点
while (!emptyQueue(sq)) { //队为空结束循环
ver = deQueue(sq, v); //出队,并得到出队信息
p = LG->adjList[ver].firstEdge; //指向出队的第一个邻接点
while (p != NULL) { //查找 ver 的所有邻接点
if (visitedBFS[p->adjVer] == 0 && p->weight != INF) { //如果没被访问
printf("%2d", p->adjVer); //打印该顶点信息
visitedBFS[p->adjVer] = 1; //置已访问状态
enQueue(sq, p->adjVer); //该顶点进队
}
p = p->nextEdge; //找下一个邻接点
}
}
printf("\n");
}