基于算法导论图算法-广度优先搜索
- 题目描述
- 问题分析
- 源代码
- 结果截图
题目描述
使用广度优先搜索遍历图:
输入:图G和源顶点s
输出:从s到所有顶点的最短距离
问题分析
广搜的思想类似水滴的扩散,在此不再赘述。
本例中一开始所有节点为白色,进队列后变为灰色,出队列后变为黑色。
伪代码
源代码
以下代码基于图论(一)–图的建立中代码创建的图G进行编写
void BFS(Graph G, Vertex s);//广度优先搜索
void print_path_twoPoint(Graph G, Vertex s, Vertex v);//打印两点路径
void print_dist(Graph G, Vertex s);//打印各顶点到顶点s的距离和路径
图的点结构需要变化
struct VertexRecord {
Vertex pred;//先驱结点
int in_degree;//入度
int out_degree;//出度
int color;//顶点状态
int dist;//距离源点的距离
List adjto;//指向第一个邻接结点的指针
};
#include<queue>
void print_path_twoPoint(Graph G,Vertex s, Vertex v) {
if (v == s) {
printf(" %d",s);
}else if(G->vertices[v].pred == -1){
printf("无相应路径");
}
else {
print_path_twoPoint(G, s, G->vertices[v].pred);
printf(" %d", v);
}
}
void print_dist(Graph G , Vertex s) {//打印各顶点到顶点s的距离和路径
for (int i = 0; i < G->vexnum; i++) {
printf("顶点%d与%d的距离:%d,路径为:", s, i, G->vertices[i].dist);
print_path_twoPoint(G, s, i);
printf("\n");
}
}
void BFS(Graph G, Vertex s) {
Vertex u, v;
PtrToNode ptr;
for (int i = 0; i < G->vexnum; i++) {
G->vertices[i].color = 0;//白色,表示未搜索
G->vertices[i].dist = INF;
G->vertices[i].pred = -1;
}
G->vertices[s].color = 1;//灰色,在队列里
G->vertices[s].dist = 0;
G->vertices[s].pred = -1;
queue<Vertex> Q;
Q.push(s);
//int count = 0;
while (!Q.empty()) {
u = Q.front();
Q.pop();
ptr = G->vertices[u].adjto;
while (ptr != NULL) {
v = ptr->adjvex;
if (G->vertices[v].color == 0) {
G->vertices[v].color = 1;
G->vertices[v].dist = G->vertices[u].dist + 1;//权为1计算
G->vertices[v].pred = u;
Q.push(v);
}
ptr = ptr->next;
}
G->vertices[u].color = 2;//黑色
printf("%d ", u);
}
printf("\n");
print_dist(G, s);
}
int main() {
//有向图的随机生成(20个顶点,100左右的边,可以进行修改)
//CreateRandomDirectGraph();
//Graph G = CreateDirectGraph();
//无向边的随机生成(20个顶点,50左右的边)
CreateRandomUndirectGraph();
Graph G = CreateUndirectGraph();
printf("打印图结构:\n");
print_graph(G);//打印图
//printf("\n打印各顶点入度和出度:\n");
//print_VertexDegree(G);//打印顶点度数
//printf("\n打印每条边的权值:\n");
//print_EdgeWeight(G);//打印边权
printf("\n下面是bfs:\n");
BFS(G, 0);
return 0;
}
结果截图